LCOV - code coverage report
Current view: top level - corosio/native/detail/reactor - reactor_socket_service.hpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 100.0 % 35 35
Test Date: 2026-10-08 18:13:32 Functions: 92.6 % 108 100 8

           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
        

Generated by: LCOV version 2.3