added fixes to void error and included bind fails

This commit is contained in:
keldu.magnus 2021-06-29 22:39:27 +02:00
parent 92e45d56d6
commit 438197033d
8 changed files with 79 additions and 22 deletions

View File

@ -147,7 +147,11 @@ Own<Server> UnixNetworkAddress::listen() {
::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
addresses.front().bind(fd);
bool failed = addresses.front().bind(fd);
if(failed){
return nullptr;
}
::listen(fd, SOMAXCONN);
return heap<UnixServer>(event_port, fd, 0);

View File

@ -344,12 +344,13 @@ public:
return result;
}
void bind(int fd) const {
bool bind(int fd) const {
if (wildcard) {
int value = 0;
::setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &value, sizeof(value));
}
::bind(fd, &address.generic, address_length);
int error = ::bind(fd, &address.generic, address_length);
return error > 0;
}
const struct ::sockaddr *getRaw() const { return &address.generic; }

View File

@ -201,6 +201,8 @@ public:
fromConveyor(Conveyor<T> &&conveyor);
};
template <typename Func> ConveyorResult<Func, void> execLater(Func &&func);
/*
* Join Conveyors into a single one
*/
@ -264,6 +266,27 @@ class SinkConveyorNode;
class ConveyorSinks final : public Event {
private:
/*
class Helper final : public Event {
private:
void destroySinkConveyorNode(ConveyorNode& sink);
void fail(Error&& error);
std::vector<Own<ConveyorNode>> sink_nodes;
std::queue<ConveyorNode*> delete_nodes;
std::function<void(Error&& error)> error_handler;
public:
ConveyorSinks() = default;
ConveyorSinks(EventLoop& event_loop);
void add(Conveyor<void> node);
void fire() override {}
};
gin::Own<Helper> helper;
*/
friend class SinkConveyorNode;
void destroySinkConveyorNode(ConveyorNode &sink_node);
@ -276,6 +299,8 @@ private:
std::function<void(Error &&error)> error_handler;
public:
// ConveyorSinks();
// ConveyorSinks(EventLoop& event_loop);
ConveyorSinks() = default;
ConveyorSinks(EventLoop &event_loop);
@ -414,7 +439,7 @@ protected:
private:
AdaptConveyorFeeder<T> *feeder = nullptr;
std::queue<ErrorOr<T>> storage;
std::queue<ErrorOr<UnfixVoid<T>>> storage;
public:
~AdaptConveyorNode();
@ -601,8 +626,9 @@ public:
error_func{std::move(error_func)} {}
void getImpl(ErrorOrValue &err_or_val) noexcept override {
ErrorOr<DepT> dep_eov;
ErrorOr<RemoveErrorOr<T>> &eov = err_or_val.as<RemoveErrorOr<T>>();
ErrorOr<UnfixVoid<DepT>> dep_eov;
ErrorOr<UnfixVoid<RemoveErrorOr<T>>> &eov =
err_or_val.as<UnfixVoid<RemoveErrorOr<T>>>();
if (child) {
child->getResult(dep_eov);
if (dep_eov.isValue()) {
@ -665,7 +691,7 @@ public:
// ConveyorStorage
void childFired() override {
if (child) {
ErrorOr<Void> dep_eov;
ErrorOr<void> dep_eov;
child->getResult(dep_eov);
if (dep_eov.isError()) {
if (dep_eov.error().isCritical()) {
@ -706,7 +732,8 @@ public:
// ConveyorNode
void getResult(ErrorOrValue &err_or_val) noexcept override {
if (retrieved > 0) {
err_or_val.as<FixVoid<T>>() = criticalError("Already taken value");
err_or_val.as<FixVoid<T>>() =
makeError("Already taken value", Error::Code::Exhausted);
} else {
err_or_val.as<FixVoid<T>>() = std::move(value);
}

View File

@ -4,6 +4,11 @@
// Template inlining
namespace gin {
template <typename Func> ConveyorResult<Func, void> execLater(Func &&func) {
Conveyor<void> conveyor{FixVoid<void>{}};
return conveyor.then(std::move(func));
}
template <typename T>
ImmediateConveyorNode<T>::ImmediateConveyorNode(FixVoid<T> &&val)
: value{std::move(val)}, retrieved{0} {}

View File

@ -56,12 +56,16 @@ Error Error::copyError() const {
Error::Code Error::code() const { return static_cast<Error::Code>(error_); }
Error makeError(const std::string_view &generic, Error::Code code) {
return Error{generic, code};
}
Error criticalError(const std::string_view &generic, Error::Code c) {
return Error{generic, c};
return makeError(generic, c);
}
Error recoverableError(const std::string_view &generic, Error::Code c) {
return Error{generic, c};
return makeError(generic, c);
}
Error noError() { return Error{}; }

View File

@ -18,7 +18,7 @@ public:
GenericCritical = -1,
GenericRecoverable = 1,
Disconnected = -99,
Exhausted = 99
Exhausted = -98
};
private:
@ -46,6 +46,8 @@ public:
Code code() const;
};
Error makeError(const std::string_view &generic, Error::Code c);
template <typename Formatter>
Error makeError(const Formatter &formatter, Error::Code code,
const std::string_view &generic) {
@ -88,19 +90,21 @@ class ErrorOrValue {
public:
virtual ~ErrorOrValue() = default;
template <typename T> ErrorOr<T> &as() {
return dynamic_cast<ErrorOr<T> &>(*this);
template <typename T> ErrorOr<UnfixVoid<T>> &as() {
return dynamic_cast<ErrorOr<UnfixVoid<T>> &>(*this);
}
template <typename T> const ErrorOr<T> &as() const {
return dynamic_cast<const ErrorOr<T> &>(*this);
template <typename T> const ErrorOr<UnfixVoid<T>> &as() const {
return dynamic_cast<const ErrorOr<UnfixVoid<T>> &>(*this);
}
};
template <typename T> class ErrorOr : public ErrorOrValue {
template <typename T> class ErrorOr final : public ErrorOrValue {
private:
std::variant<Error, FixVoid<T>> value_or_error;
static_assert(!std::is_same_v<T, Void>, "Don't use internal private types");
public:
ErrorOr() = default;
ErrorOr(const FixVoid<T> &value) : value_or_error{value} {}
@ -110,7 +114,9 @@ public:
ErrorOr(const Error &error) : value_or_error{error} {}
ErrorOr(Error &&error) : value_or_error{std::move(error)} {}
bool isValue() const { return std::holds_alternative<T>(value_or_error); }
bool isValue() const {
return std::holds_alternative<FixVoid<T>>(value_or_error);
}
bool isError() const {
return std::holds_alternative<Error>(value_or_error);

View File

@ -4,15 +4,22 @@
#include "io.h"
namespace gin {
/*
template<typename Codec, typename Incoming, typename Outgoing>
template <typename Codec, typename Incoming, typename Outgoing>
class StreamingIoPeer {
private:
Codec codec;
Own<AsyncIoStream> io_stream;
Own<ConveyorFeeder<Incoming>> incoming_feeder = nullptr;
public:
void send(Outgoing&& outgoing);
StreamingIoPeer(Own<AsyncIoStream> stream);
void send(Outgoing outgoing, Own<MessageBuilder> builder);
Conveyor<Incoming> startReadPump();
};
*/
}
} // namespace gin

View File

@ -92,6 +92,9 @@ TlsServer::TlsServer(Own<Server> srv) : internal{std::move(srv)} {}
Conveyor<Own<IoStream>> TlsServer::accept() {
GIN_ASSERT(internal) { return Conveyor<Own<IoStream>>{nullptr, nullptr}; }
return internal->accept().then([](Own<IoStream> stream) -> Own<IoStream> {
/// @todo handshake
return heap<TlsIoStream>(std::move(stream));
});
}