src/corosio/src/detail/epoll/acceptors.hpp

100.0% Lines (14/14) 100.0% Functions (6/6)
src/corosio/src/detail/epoll/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_EPOLL_ACCEPTORS_HPP
11 #define BOOST_COROSIO_DETAIL_EPOLL_ACCEPTORS_HPP
12
13 #include <boost/corosio/detail/platform.hpp>
14
15 #if BOOST_COROSIO_HAS_EPOLL
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/epoll/op.hpp"
25 #include "src/detail/epoll/scheduler.hpp"
26
27 #include <memory>
28 #include <mutex>
29 #include <unordered_map>
30
31 namespace boost::corosio::detail {
32
33 class epoll_acceptor_service;
34 class epoll_acceptor_impl;
35 class epoll_socket_service;
36
37 /// Acceptor implementation for epoll backend.
38 class epoll_acceptor_impl final
39 : public tcp_acceptor::implementation
40 , public std::enable_shared_from_this<epoll_acceptor_impl>
41 , public intrusive_list<epoll_acceptor_impl>::node
42 {
43 friend class epoll_acceptor_service;
44
45 public:
46 explicit epoll_acceptor_impl(epoll_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 4861 endpoint local_endpoint() const noexcept override
60 {
61 4861 return local_endpoint_;
62 }
63 5064 bool is_open() const noexcept override
64 {
65 5064 return fd_ >= 0;
66 }
67 void cancel() noexcept override;
68 void cancel_single_op(epoll_op& op) noexcept;
69 void close_socket() noexcept;
70 62 void set_local_endpoint(endpoint ep) noexcept
71 {
72 62 local_endpoint_ = ep;
73 62 }
74
75 9637 epoll_acceptor_service& service() noexcept
76 {
77 9637 return svc_;
78 }
79
80 epoll_accept_op acc_;
81 descriptor_state desc_state_;
82
83 private:
84 epoll_acceptor_service& svc_;
85 int fd_ = -1;
86 endpoint local_endpoint_;
87 };
88
89 /** State for epoll acceptor service. */
90 class epoll_acceptor_state
91 {
92 public:
93 203 explicit epoll_acceptor_state(epoll_scheduler& sched) noexcept
94 203 : sched_(sched)
95 {
96 203 }
97
98 epoll_scheduler& sched_;
99 std::mutex mutex_;
100 intrusive_list<epoll_acceptor_impl> acceptor_list_;
101 std::unordered_map<
102 epoll_acceptor_impl*,
103 std::shared_ptr<epoll_acceptor_impl>>
104 acceptor_ptrs_;
105 };
106
107 /** epoll acceptor service implementation.
108
109 Inherits from acceptor_service to enable runtime polymorphism.
110 Uses key_type = acceptor_service for service lookup.
111 */
112 class epoll_acceptor_service final : public acceptor_service
113 {
114 public:
115 explicit epoll_acceptor_service(capy::execution_context& ctx);
116 ~epoll_acceptor_service() override;
117
118 epoll_acceptor_service(epoll_acceptor_service const&) = delete;
119 epoll_acceptor_service& operator=(epoll_acceptor_service const&) = delete;
120
121 void shutdown() override;
122
123 io_object::implementation* construct() override;
124 void destroy(io_object::implementation*) override;
125 void close(io_object::handle&) override;
126 std::error_code open_acceptor(
127 tcp_acceptor::implementation& impl, endpoint ep, int backlog) override;
128
129 4949 epoll_scheduler& scheduler() const noexcept
130 {
131 4949 return state_->sched_;
132 }
133 void post(epoll_op* op);
134 void work_started() noexcept;
135 void work_finished() noexcept;
136
137 /** Get the socket service for creating peer sockets during accept. */
138 epoll_socket_service* socket_service() const noexcept;
139
140 private:
141 capy::execution_context& ctx_;
142 std::unique_ptr<epoll_acceptor_state> state_;
143 };
144
145 } // namespace boost::corosio::detail
146
147 #endif // BOOST_COROSIO_HAS_EPOLL
148
149 #endif // BOOST_COROSIO_DETAIL_EPOLL_ACCEPTORS_HPP
150