// // Copyright (c) 2025 Klemens Morgenstern (klemens.morgenstern@gmx.net) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef BOOST_COBALT_EXPERIMENTAL_IO_ACCEPTOR_HPP #define BOOST_COBALT_EXPERIMENTAL_IO_ACCEPTOR_HPP #include #include #include #include #include namespace boost::cobalt::io { struct BOOST_SYMBOL_VISIBLE acceptor { using wait_type = asio::socket_base::wait_type; constexpr static std::size_t max_listen_connections = asio::socket_base::max_listen_connections; BOOST_COBALT_IO_DECL acceptor(const cobalt::executor & executor = this_thread::get_executor()); BOOST_COBALT_IO_DECL acceptor(endpoint ep, const cobalt::executor & executor = this_thread::get_executor()); BOOST_COBALT_IO_DECL system::result bind(endpoint ep); BOOST_COBALT_IO_DECL system::result listen(int backlog = max_listen_connections); // int backlog = net::max_backlog() BOOST_COBALT_IO_DECL endpoint local_endpoint(); private: struct BOOST_COBALT_IO_DECL accept_op final : op { void initiate(completion_handler h) override; accept_op(accept_op &&) noexcept = default; accept_op(asio::basic_socket_acceptor & acceptor, socket& sock) : acceptor_(acceptor), sock_(sock) {} ~accept_op() = default; protected: asio::basic_socket_acceptor &acceptor_; socket & sock_; }; struct BOOST_COBALT_IO_DECL accept_stream_op final : op { void initiate(completion_handler h) override; accept_stream_op(accept_stream_op &&) noexcept = default; accept_stream_op(asio::basic_socket_acceptor & acceptor) : acceptor_(acceptor) {} ~accept_stream_op() = default; private: asio::basic_socket_acceptor &acceptor_; stream_socket sock_{acceptor_.get_executor()}; }; struct BOOST_COBALT_IO_DECL accept_seq_packet_op final : op { void initiate(completion_handler h) override; accept_seq_packet_op(accept_seq_packet_op &&) noexcept = default; accept_seq_packet_op(asio::basic_socket_acceptor & acceptor) : acceptor_(acceptor) {} ~accept_seq_packet_op() = default; private: asio::basic_socket_acceptor &acceptor_; seq_packet_socket sock_{acceptor_.get_executor()}; }; struct BOOST_COBALT_IO_DECL wait_op final : op { void initiate(completion_handler h) override; wait_op(asio::basic_socket_acceptor & acceptor, wait_type wt) : acceptor_(acceptor), wt_(wt) {} ~wait_op() = default; private: asio::basic_socket_acceptor &acceptor_; wait_type wt_; }; public: [[nodiscard]] accept_op accept(socket & sock) { return accept_op{acceptor_, sock}; } template [[nodiscard]] accept_stream_op accept(static_protocol stream_proto = tcp) { return accept_stream_op{acceptor_}; } template [[nodiscard]] accept_seq_packet_op accept(static_protocol stream_proto) { return accept_seq_packet_op{acceptor_}; } [[nodiscard]] wait_op wait(wait_type wt = wait_type::wait_read) { return {acceptor_, wt}; } private: asio::basic_socket_acceptor acceptor_; }; } #endif //BOOST_COBALT_EXPERIMENTAL_IO_ACCEPTOR_HPP