Line data 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/socket_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
39 : : public tcp_acceptor::acceptor_impl
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 : void release() override;
49 :
50 : void accept(
51 : std::coroutine_handle<>,
52 : capy::executor_ref,
53 : std::stop_token,
54 : std::error_code*,
55 : io_object::io_object_impl**) override;
56 :
57 : int native_handle() const noexcept { return fd_; }
58 10 : endpoint local_endpoint() const noexcept override { return local_endpoint_; }
59 : bool is_open() const noexcept { return fd_ >= 0; }
60 : void cancel() noexcept override;
61 : void cancel_single_op(epoll_op& op) noexcept;
62 : void close_socket() noexcept;
63 : void update_epoll_events() noexcept;
64 57 : void set_local_endpoint(endpoint ep) noexcept { local_endpoint_ = ep; }
65 :
66 2642 : epoll_acceptor_service& service() noexcept { return svc_; }
67 :
68 : epoll_accept_op acc_;
69 : descriptor_data desc_data_;
70 :
71 : private:
72 : epoll_acceptor_service& svc_;
73 : int fd_ = -1;
74 : endpoint local_endpoint_;
75 : };
76 :
77 : /** State for epoll acceptor service. */
78 : class epoll_acceptor_state
79 : {
80 : public:
81 184 : explicit epoll_acceptor_state(epoll_scheduler& sched) noexcept
82 184 : : sched_(sched)
83 : {
84 184 : }
85 :
86 : epoll_scheduler& sched_;
87 : std::mutex mutex_;
88 : intrusive_list<epoll_acceptor_impl> acceptor_list_;
89 : std::unordered_map<epoll_acceptor_impl*, std::shared_ptr<epoll_acceptor_impl>> acceptor_ptrs_;
90 : };
91 :
92 : /** epoll acceptor service implementation.
93 :
94 : Inherits from acceptor_service to enable runtime polymorphism.
95 : Uses key_type = acceptor_service for service lookup.
96 : */
97 : class epoll_acceptor_service : public acceptor_service
98 : {
99 : public:
100 : explicit epoll_acceptor_service(capy::execution_context& ctx);
101 : ~epoll_acceptor_service();
102 :
103 : epoll_acceptor_service(epoll_acceptor_service const&) = delete;
104 : epoll_acceptor_service& operator=(epoll_acceptor_service const&) = delete;
105 :
106 : void shutdown() override;
107 :
108 : tcp_acceptor::acceptor_impl& create_acceptor_impl() override;
109 : void destroy_acceptor_impl(tcp_acceptor::acceptor_impl& impl) override;
110 : std::error_code open_acceptor(
111 : tcp_acceptor::acceptor_impl& impl,
112 : endpoint ep,
113 : int backlog) override;
114 :
115 114 : epoll_scheduler& scheduler() const noexcept { return state_->sched_; }
116 : void post(epoll_op* op);
117 : void work_started() noexcept;
118 : void work_finished() noexcept;
119 :
120 : /** Get the socket service for creating peer sockets during accept. */
121 : epoll_socket_service* socket_service() const noexcept;
122 :
123 : private:
124 : capy::execution_context& ctx_;
125 : std::unique_ptr<epoll_acceptor_state> state_;
126 : };
127 :
128 : } // namespace boost::corosio::detail
129 :
130 : #endif // BOOST_COROSIO_HAS_EPOLL
131 :
132 : #endif // BOOST_COROSIO_DETAIL_EPOLL_ACCEPTORS_HPP
|