include/boost/corosio/native/detail/reactor/reactor_descriptor_service.hpp

100.0% Lines (47 / 47) 100.0% Functions (20 / 20)
reactor_descriptor_service.hpp
f(x) Functions (20)
Function Calls Lines Blocks
boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::epoll_descriptor_service, boost::corosio::detail::epoll_traits, boost::corosio::detail::epoll_descriptor>::reactor_descriptor_service(boost::capy::execution_context&) :60 53x 100.0% 83.0% boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::select_descriptor_service, boost::corosio::detail::select_traits, boost::corosio::detail::select_descriptor>::reactor_descriptor_service(boost::capy::execution_context&) :60 52x 100.0% 83.0% boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::epoll_descriptor_service, boost::corosio::detail::epoll_traits, boost::corosio::detail::epoll_descriptor>::~reactor_descriptor_service() :72 53x 100.0% 100.0% boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::select_descriptor_service, boost::corosio::detail::select_traits, boost::corosio::detail::select_descriptor>::~reactor_descriptor_service() :72 52x 100.0% 100.0% boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::epoll_descriptor_service, boost::corosio::detail::epoll_traits, boost::corosio::detail::epoll_descriptor>::shutdown() :78 53x 100.0% 100.0% boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::select_descriptor_service, boost::corosio::detail::select_traits, boost::corosio::detail::select_descriptor>::shutdown() :78 52x 100.0% 100.0% boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::epoll_descriptor_service, boost::corosio::detail::epoll_traits, boost::corosio::detail::epoll_descriptor>::construct() :89 61x 100.0% 74.0% boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::select_descriptor_service, boost::corosio::detail::select_traits, boost::corosio::detail::select_descriptor>::construct() :89 60x 100.0% 74.0% boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::epoll_descriptor_service, boost::corosio::detail::epoll_traits, boost::corosio::detail::epoll_descriptor>::destroy(boost::corosio::io_object::implementation*) :103 54x 100.0% 83.0% boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::select_descriptor_service, boost::corosio::detail::select_traits, boost::corosio::detail::select_descriptor>::destroy(boost::corosio::io_object::implementation*) :103 53x 100.0% 83.0% boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::epoll_descriptor_service, boost::corosio::detail::epoll_traits, boost::corosio::detail::epoll_descriptor>::close(boost::corosio::io_object::handle&) :112 99x 100.0% 100.0% boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::select_descriptor_service, boost::corosio::detail::select_traits, boost::corosio::detail::select_descriptor>::close(boost::corosio::io_object::handle&) :112 96x 100.0% 100.0% boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::epoll_descriptor_service, boost::corosio::detail::epoll_traits, boost::corosio::detail::epoll_descriptor>::scheduler() const :117 135x 100.0% 100.0% boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::select_descriptor_service, boost::corosio::detail::select_traits, boost::corosio::detail::select_descriptor>::scheduler() const :117 161x 100.0% 100.0% boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::epoll_descriptor_service, boost::corosio::detail::epoll_traits, boost::corosio::detail::epoll_descriptor>::post(boost::corosio::detail::scheduler_op*) :122 35x 100.0% 100.0% boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::select_descriptor_service, boost::corosio::detail::select_traits, boost::corosio::detail::select_descriptor>::post(boost::corosio::detail::scheduler_op*) :122 36x 100.0% 100.0% boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::epoll_descriptor_service, boost::corosio::detail::epoll_traits, boost::corosio::detail::epoll_descriptor>::work_started() :127 28x 100.0% 100.0% boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::select_descriptor_service, boost::corosio::detail::select_traits, boost::corosio::detail::select_descriptor>::work_started() :127 27x 100.0% 100.0% boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::epoll_descriptor_service, boost::corosio::detail::epoll_traits, boost::corosio::detail::epoll_descriptor>::work_finished() :132 14x 100.0% 100.0% boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::select_descriptor_service, boost::corosio::detail::select_traits, boost::corosio::detail::select_descriptor>::work_finished() :132 16x 100.0% 100.0%
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Michael Vandeberg
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_NATIVE_DETAIL_REACTOR_REACTOR_DESCRIPTOR_SERVICE_HPP
11 #define BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_DESCRIPTOR_SERVICE_HPP
12
13 #include <boost/corosio/detail/platform.hpp>
14
15 #if BOOST_COROSIO_POSIX
16
17 #include <boost/corosio/detail/descriptor_service.hpp>
18 #include <boost/corosio/detail/scheduler_op.hpp>
19 #include <boost/corosio/native/detail/validate_fd.hpp>
20 #include <boost/corosio/native/detail/reactor/reactor_descriptor.hpp>
21 #include <boost/corosio/native/detail/reactor/reactor_service_state.hpp>
22 #include <boost/capy/ex/execution_context.hpp>
23
24 #include <memory>
25 #include <mutex>
26 #include <system_error>
27
28 /* Reactor-backed descriptor_service.
29
30 assign_descriptor is the validate-before-mutate core the public
31 assign() contract rests on, modelled on do_assign_fd in
32 reactor_service_finals.hpp.
33
34 PARALLEL COPY: construct, destroy, close and shutdown here mirror the
35 same four members of reactor_socket_service.hpp, which this cannot
36 reuse because it calls close_socket() by name. A fix to the service
37 lifecycle -- the construct/destroy bookkeeping under state_->mutex_,
38 or shutdown's deliberate retention of impl_ptrs_ so impls outlive the
39 scheduler's drain -- belongs in both files.
40 */
41
42 namespace boost::corosio::detail {
43
44 /** CRTP base for reactor-backed descriptor services.
45
46 @tparam Derived The named final service type (CRTP self).
47 @tparam Traits Backend traits (epoll_traits, kqueue_traits, ...).
48 @tparam DescFinal The named final descriptor impl type.
49 */
50 template<class Derived, class Traits, class DescFinal>
51 class reactor_descriptor_service : public descriptor_service
52 {
53 using scheduler_type = typename Traits::scheduler_type;
54 using state_type = reactor_service_state<scheduler_type, DescFinal>;
55
56 friend Derived;
57
58 protected:
59 // NOLINTNEXTLINE(bugprone-crtp-constructor-accessibility)
60 105x explicit reactor_descriptor_service(capy::execution_context& ctx)
61 105x : state_(
62 std::make_unique<state_type>(
63 105x ctx.template use_service<scheduler_type>()))
64 {
65 105x }
66
67 public:
68 /// True when any parked op must wake the reactor.
69 static constexpr bool needs_park_notification =
70 Traits::needs_park_notification;
71
72 105x ~reactor_descriptor_service() override = default;
73
74 std::error_code assign_descriptor(
75 posix_stream_descriptor::implementation& impl,
76 native_handle_type fd) override;
77
78 105x void shutdown() override
79 {
80 105x std::lock_guard lock(state_->mutex_);
81
82 119x while (auto* impl = state_->impl_list_.pop_front())
83 14x impl->close_descriptor();
84
85 // Don't clear impl_ptrs_ here: the scheduler shuts down after us
86 // and drains completed_ops_, so every impl must outlive that.
87 105x }
88
89 121x io_object::implementation* construct() override
90 {
91 121x auto impl = std::make_shared<DescFinal>(static_cast<Derived&>(*this));
92 121x auto* raw = impl.get();
93
94 {
95 121x std::lock_guard lock(state_->mutex_);
96 121x state_->impl_ptrs_.emplace(raw, std::move(impl));
97 121x state_->impl_list_.push_back(raw);
98 121x }
99
100 121x return raw;
101 121x }
102
103 107x void destroy(io_object::implementation* impl) override
104 {
105 107x auto* typed = static_cast<DescFinal*>(impl);
106 107x typed->close_descriptor();
107 107x std::lock_guard lock(state_->mutex_);
108 107x state_->impl_list_.remove(typed);
109 107x state_->impl_ptrs_.erase(typed);
110 107x }
111
112 195x void close(io_object::handle& h) override
113 {
114 195x static_cast<DescFinal*>(h.get())->close_descriptor();
115 195x }
116
117 296x scheduler_type& scheduler() const noexcept
118 {
119 296x return state_->sched_;
120 }
121
122 71x void post(scheduler_op* op)
123 {
124 71x state_->sched_.post(op);
125 71x }
126
127 55x void work_started() noexcept
128 {
129 55x state_->sched_.work_started();
130 55x }
131
132 30x void work_finished() noexcept
133 {
134 30x state_->sched_.work_finished();
135 30x }
136
137 protected:
138 std::unique_ptr<state_type> state_;
139
140 private:
141 reactor_descriptor_service(reactor_descriptor_service const&) = delete;
142 reactor_descriptor_service&
143 operator=(reactor_descriptor_service const&) = delete;
144 };
145
146 template<class Derived, class Traits, class DescFinal>
147 std::error_code
148 111x reactor_descriptor_service<Derived, Traits, DescFinal>::assign_descriptor(
149 posix_stream_descriptor::implementation& impl_base, native_handle_type fd)
150 {
151 111x auto* impl = static_cast<DescFinal*>(&impl_base);
152
153 // The public assign() guarantees the object is closed.
154 111x if (auto ec = validate_descriptor_fd(fd))
155 4x return ec;
156
157 if constexpr (requires { Traits::max_descriptor; })
158 {
159 53x if (fd >= Traits::max_descriptor)
160 1x return make_err(EMFILE);
161 }
162
163 106x return impl->init_and_register(fd);
164 }
165
166 } // namespace boost::corosio::detail
167
168 #endif // BOOST_COROSIO_POSIX
169
170 #endif // BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_DESCRIPTOR_SERVICE_HPP
171