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)); ::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); ::listen(fd, SOMAXCONN);
return heap<UnixServer>(event_port, fd, 0); return heap<UnixServer>(event_port, fd, 0);

View File

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

View File

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

View File

@ -4,6 +4,11 @@
// Template inlining // Template inlining
namespace gin { 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> template <typename T>
ImmediateConveyorNode<T>::ImmediateConveyorNode(FixVoid<T> &&val) ImmediateConveyorNode<T>::ImmediateConveyorNode(FixVoid<T> &&val)
: value{std::move(val)}, retrieved{0} {} : 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::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) { 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) { Error recoverableError(const std::string_view &generic, Error::Code c) {
return Error{generic, c}; return makeError(generic, c);
} }
Error noError() { return Error{}; } Error noError() { return Error{}; }

View File

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

View File

@ -4,15 +4,22 @@
#include "io.h" #include "io.h"
namespace gin { namespace gin {
/*
template<typename Codec, typename Incoming, typename Outgoing> template <typename Codec, typename Incoming, typename Outgoing>
class StreamingIoPeer { class StreamingIoPeer {
private: private:
Codec codec; Codec codec;
Own<AsyncIoStream> io_stream;
Own<ConveyorFeeder<Incoming>> incoming_feeder = nullptr;
public: public:
void send(Outgoing&& outgoing); StreamingIoPeer(Own<AsyncIoStream> stream);
void send(Outgoing outgoing, Own<MessageBuilder> builder);
Conveyor<Incoming> startReadPump(); 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() { Conveyor<Own<IoStream>> TlsServer::accept() {
GIN_ASSERT(internal) { return Conveyor<Own<IoStream>>{nullptr, nullptr}; } GIN_ASSERT(internal) { return Conveyor<Own<IoStream>>{nullptr, nullptr}; }
return internal->accept().then([](Own<IoStream> stream) -> Own<IoStream> { return internal->accept().then([](Own<IoStream> stream) -> Own<IoStream> {
/// @todo handshake
return heap<TlsIoStream>(std::move(stream)); return heap<TlsIoStream>(std::move(stream));
}); });
} }