From a38639b2293f9e74dbd61407cf862366039fed9c Mon Sep 17 00:00:00 2001 From: Benny Baumann <BenBE@geshi.org> Date: Fri, 1 Jan 2021 17:25:41 +0100 Subject: [PATCH] Basic work on async socket interface --- src/net/async_fd.hpp | 85 ++++++++++++++++++++++++++++++++++++++++ src/net/async_server.hpp | 40 +++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 src/net/async_fd.hpp create mode 100644 src/net/async_server.hpp diff --git a/src/net/async_fd.hpp b/src/net/async_fd.hpp new file mode 100644 index 0000000..72a42d7 --- /dev/null +++ b/src/net/async_fd.hpp @@ -0,0 +1,85 @@ +#pragma once + +#include <unistd.h> + +namespace rmrf::net { + + class null_fd + { + public: + constexpr explicit null_fd() {} + constexpr explicit null_fd(int) {} + constexpr operator int() const { return -1; } + }; + + constexpr null_fd nullfd{}; + + class auto_fd + { + private: + int _fd; + + public: + inline auto_fd(null_fd nfd = nullfd) noexcept : _fd{nfd} {} + + explicit inline auto_fd(int fd) noexcept : _fd{fd} {} + + inline auto_fd(auto_fd &&fd) noexcept : _fd{fd.release()} {} + inline auto_fd &operator=(auto_fd &&fd) noexcept { + reset(fd.release()); + return *this; + } + + auto_fd(const auto_fd &) = delete; + auto_fd &operator=(const auto_fd &) = delete; + + inline ~auto_fd() noexcept { + reset(); + } + + inline int get() const noexcept { return _fd; } + + int release() noexcept + { + int r(_fd); + _fd = -1; + return r; + } + + // Close an open file descriptor. Reset the descriptor to -1. + inline void close() noexcept { + if (_fd >= 0) + { + ::close(_fd); + + // If fdclose() failed then no reason to expect it to succeed the next time. + _fd = -1; + } + } + + inline void reset(int fd = -1) noexcept { + if (_fd >= 0) + close(); // Don't check for an error as not much we can do here. + + _fd = fd; + } + + }; + + inline bool operator==(const auto_fd &x, const auto_fd &y) { + return x.get() == y.get(); + } + + inline bool operator!=(const auto_fd &x, const auto_fd &y) { + return !(x == y); + } + + inline bool operator==(const auto_fd &x, null_fd) { + return x.get() == -1; + } + + inline bool operator!=(const auto_fd &x, null_fd y) { + return !(x == y); + } + +} diff --git a/src/net/async_server.hpp b/src/net/async_server.hpp new file mode 100644 index 0000000..f192884 --- /dev/null +++ b/src/net/async_server.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include <functional> +#include <memory> + +#include <net/async_fd.hpp> + +namespace rmrf::net::asio { + +class async_server_socket : public std::enable_shared_from_this<async_server_socket> { +public: + typedef std::shared_ptr<async_server_socket> self_ptr_type; + + typedef std::function<void(self_ptr_type&, const auto_fd &)> accept_handler_type; + typedef std::function<void(self_ptr_type&)> error_handler_type; + +private: + auto_fd socket; + + accept_handler_type on_accept; + error_handler_type on_error; + +public: + async_server_socket(auto_fd&& fd) : socket(std::forward(fd)) { + // Add this socket to libev ... + } + ~async_server_socket() { + // Remove this socket from libev ... + } + +public: + accept_handler_type get_accept_handler() const { + return on_accept; + } + void set_accept_handler(const accept_handler_type& value) { + on_accept = value; + } +}; + +} -- GitLab