TLA 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_NATIVE_DETAIL_REACTOR_REACTOR_SOCKET_SERVICE_HPP
11 : #define BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_SOCKET_SERVICE_HPP
12 :
13 : #include <boost/corosio/io/io_object.hpp>
14 : #include <boost/corosio/detail/object_ref.hpp>
15 : #include <boost/corosio/detail/scheduler_op.hpp>
16 : #include <boost/corosio/native/detail/reactor/reactor_service_state.hpp>
17 : #include <boost/capy/ex/execution_context.hpp>
18 :
19 : #include <memory>
20 :
21 : namespace boost::corosio::detail {
22 :
23 : /** CRTP base for reactor-backed socket/datagram service implementations.
24 :
25 : Provides the shared construct/destroy/shutdown/close/post/work
26 : logic that is identical across all reactor backends and socket
27 : types. Derived classes add only protocol-specific open/bind.
28 :
29 : @tparam Derived The concrete service type (CRTP).
30 : @tparam ServiceBase The abstract service base (tcp_service
31 : or udp_service).
32 : @tparam Scheduler The backend's scheduler type.
33 : @tparam Impl The backend's socket/datagram impl type.
34 : */
35 : template<class Derived, class ServiceBase, class Scheduler, class Impl>
36 : class reactor_socket_service : public ServiceBase
37 : {
38 : friend Derived;
39 :
40 : // The intermediate CRTP templates below (not Impl itself) are what
41 : // actually reach into state_->pool_ from retire() -- see
42 : // reactor_socket_finals.hpp.
43 : template<class, class, class, class, class, class>
44 : friend class reactor_stream_socket_impl;
45 : template<class, class, class, class, class, class>
46 : friend class reactor_dgram_socket_impl;
47 :
48 : using state_type = reactor_service_state<Scheduler, Impl>;
49 :
50 : protected:
51 : // NOLINTNEXTLINE(bugprone-crtp-constructor-accessibility)
52 HIT 1407 : explicit reactor_socket_service(capy::execution_context& ctx)
53 1407 : : state_(
54 : std::make_unique<state_type>(
55 1407 : ctx.template use_service<Scheduler>()))
56 : {
57 1407 : }
58 :
59 : public:
60 1407 : ~reactor_socket_service() override = default;
61 :
62 1407 : void shutdown() override
63 : {
64 1407 : state_->pool_.shutdown(
65 1963 : [this](Impl* impl)
66 : {
67 317 : static_cast<Derived*>(this)->pre_shutdown(impl);
68 317 : impl->close_socket();
69 : });
70 :
71 : // Queued ops still hold references (their own object_ref copy);
72 : // the scheduler shuts down after us and drains completed_ops_,
73 : // each op's destroy() releasing its reference. Shutting-down
74 : // mode makes that final release() delete instead of recycle,
75 : // so every impl stays alive until its ops are gone, then frees.
76 1407 : }
77 :
78 16052 : io_object::implementation* construct() override
79 : {
80 16052 : return state_->pool_.acquire(static_cast<Derived&>(*this));
81 : }
82 :
83 16047 : void destroy(io_object::implementation* impl) override
84 : {
85 16047 : auto* typed = static_cast<Impl*>(impl);
86 16047 : static_cast<Derived*>(this)->pre_destroy(typed);
87 16047 : typed->close_socket();
88 16047 : release(typed);
89 16047 : }
90 :
91 26637 : void close(io_object::handle& h) override
92 : {
93 26637 : static_cast<Impl*>(h.get())->close_socket();
94 26637 : }
95 :
96 480728 : Scheduler& scheduler() const noexcept
97 : {
98 480728 : return state_->sched_;
99 : }
100 :
101 92173 : void post(scheduler_op* op)
102 : {
103 92173 : state_->sched_.post(op);
104 92173 : }
105 :
106 6140 : void work_started() noexcept
107 : {
108 6140 : state_->sched_.work_started();
109 6140 : }
110 :
111 501 : void work_finished() noexcept
112 : {
113 501 : state_->sched_.work_finished();
114 501 : }
115 :
116 : protected:
117 : // Override in derived to add pre-close logic. No backend currently needs
118 : // it; the hooks exist so a trait can run fd-level teardown before close.
119 157 : void pre_shutdown(Impl*) noexcept {
120 : } // LCOV_EXCL_LINE optional CRTP hook; no backend overrides it today
121 1196 : void pre_destroy(Impl*) noexcept {}
122 :
123 : std::unique_ptr<state_type> state_;
124 :
125 : private:
126 : reactor_socket_service(reactor_socket_service const&) = delete;
127 : reactor_socket_service& operator=(reactor_socket_service const&) = delete;
128 : };
129 :
130 : } // namespace boost::corosio::detail
131 :
132 : #endif // BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_SOCKET_SERVICE_HPP
|