src/corosio/src/detail/select/acceptors.hpp

100.0% Lines (14/14) 100.0% Functions (6/6)
src/corosio/src/detail/select/acceptors.hpp
Line Hits Source Code
1 //
2 // Copyright (c) 2026 Steve Gerbino
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/cppalliance/corosio
8 //
9
10 #ifndef BOOST_COROSIO_DETAIL_SELECT_ACCEPTORS_HPP
11 #define BOOST_COROSIO_DETAIL_SELECT_ACCEPTORS_HPP
12
13 #include <boost/corosio/detail/platform.hpp>
14
15 #if BOOST_COROSIO_HAS_SELECT
16
17 #include <boost/corosio/detail/config.hpp>
18 #include <boost/corosio/tcp_acceptor.hpp>
19 #include <boost/capy/ex/executor_ref.hpp>
20 #include <boost/capy/ex/execution_context.hpp>
21 #include "src/detail/intrusive.hpp"
22 #include "src/detail/acceptor_service.hpp"
23
24 #include "src/detail/select/op.hpp"
25 #include "src/detail/select/scheduler.hpp"
26
27 #include <memory>
28 #include <mutex>
29 #include <unordered_map>
30
31 namespace boost::corosio::detail {
32
33 class select_acceptor_service;
34 class select_acceptor_impl;
35 class select_socket_service;
36
37 /// Acceptor implementation for select backend.
38 class select_acceptor_impl final
39 : public tcp_acceptor::implementation
40 , public std::enable_shared_from_this<select_acceptor_impl>
41 , public intrusive_list<select_acceptor_impl>::node
42 {
43 friend class select_acceptor_service;
44
45 public:
46 explicit select_acceptor_impl(select_acceptor_service& svc) noexcept;
47
48 std::coroutine_handle<> accept(
49 std::coroutine_handle<>,
50 capy::executor_ref,
51 std::stop_token,
52 std::error_code*,
53 io_object::implementation**) override;
54
55 int native_handle() const noexcept
56 {
57 return fd_;
58 }
59 39 endpoint local_endpoint() const noexcept override
60 {
61 39 return local_endpoint_;
62 }
63 3740 bool is_open() const noexcept override
64 {
65 3740 return fd_ >= 0;
66 }
67 void cancel() noexcept override;
68 void cancel_single_op(select_op& op) noexcept;
69 void close_socket() noexcept;
70 42 void set_local_endpoint(endpoint ep) noexcept
71 {
72 42 local_endpoint_ = ep;
73 42 }
74
75 3561 select_acceptor_service& service() noexcept
76 {
77 3561 return svc_;
78 }
79
80 select_accept_op acc_;
81
82 private:
83 select_acceptor_service& svc_;
84 int fd_ = -1;
85 endpoint local_endpoint_;
86 };
87
88 /** State for select acceptor service. */
89 class select_acceptor_state
90 {
91 public:
92 133 explicit select_acceptor_state(select_scheduler& sched) noexcept
93 133 : sched_(sched)
94 {
95 133 }
96
97 select_scheduler& sched_;
98 std::mutex mutex_;
99 intrusive_list<select_acceptor_impl> acceptor_list_;
100 std::unordered_map<
101 select_acceptor_impl*,
102 std::shared_ptr<select_acceptor_impl>>
103 acceptor_ptrs_;
104 };
105
106 /** select acceptor service implementation.
107
108 Inherits from acceptor_service to enable runtime polymorphism.
109 Uses key_type = acceptor_service for service lookup.
110 */
111 class select_acceptor_service final : public acceptor_service
112 {
113 public:
114 explicit select_acceptor_service(capy::execution_context& ctx);
115 ~select_acceptor_service() override;
116
117 select_acceptor_service(select_acceptor_service const&) = delete;
118 select_acceptor_service& operator=(select_acceptor_service const&) = delete;
119
120 void shutdown() override;
121
122 io_object::implementation* construct() override;
123 void destroy(io_object::implementation*) override;
124 void close(io_object::handle&) override;
125 std::error_code open_acceptor(
126 tcp_acceptor::implementation& impl, endpoint ep, int backlog) override;
127
128 3607 select_scheduler& scheduler() const noexcept
129 {
130 3607 return state_->sched_;
131 }
132 void post(select_op* op);
133 void work_started() noexcept;
134 void work_finished() noexcept;
135
136 /** Get the socket service for creating peer sockets during accept. */
137 select_socket_service* socket_service() const noexcept;
138
139 private:
140 capy::execution_context& ctx_;
141 std::unique_ptr<select_acceptor_state> state_;
142 };
143
144 } // namespace boost::corosio::detail
145
146 #endif // BOOST_COROSIO_HAS_SELECT
147
148 #endif // BOOST_COROSIO_DETAIL_SELECT_ACCEPTORS_HPP
149