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: 93.2 % 44 41 3
Test Date: 2026-04-09 23:21:11 Functions: 78.0 % 100 78 22

           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/scheduler_op.hpp>
      15                 : #include <boost/corosio/native/detail/reactor/reactor_service_state.hpp>
      16                 : #include <boost/capy/ex/execution_context.hpp>
      17                 : 
      18                 : #include <memory>
      19                 : #include <mutex>
      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                 :     using state_type = reactor_service_state<Scheduler, Impl>;
      40                 : 
      41                 : public:
      42                 :     /// Propagated from Scheduler for register_op's write notification.
      43                 :     static constexpr bool needs_write_notification =
      44                 :         Scheduler::needs_write_notification;
      45                 : 
      46                 : private:
      47                 : 
      48 HIT        2348 :     explicit reactor_socket_service(capy::execution_context& ctx)
      49            2348 :         : state_(
      50                 :               std::make_unique<state_type>(
      51            2348 :                   ctx.template use_service<Scheduler>()))
      52                 :     {
      53            2348 :     }
      54                 : 
      55                 : public:
      56            2348 :     ~reactor_socket_service() override = default;
      57                 : 
      58            2348 :     void shutdown() override
      59                 :     {
      60            2348 :         std::lock_guard lock(state_->mutex_);
      61                 : 
      62            2348 :         while (auto* impl = state_->impl_list_.pop_front())
      63                 :         {
      64 MIS           0 :             static_cast<Derived*>(this)->pre_shutdown(impl);
      65               0 :             impl->close_socket();
      66                 :         }
      67                 : 
      68                 :         // Don't clear impl_ptrs_ here. The scheduler shuts down after us
      69                 :         // and drains completed_ops_, calling destroy() on each queued op.
      70                 :         // Letting ~state_ release the ptrs (during service destruction,
      71                 :         // after scheduler shutdown) keeps every impl alive until all ops
      72                 :         // have been drained.
      73 HIT        2348 :     }
      74                 : 
      75           25797 :     io_object::implementation* construct() override
      76                 :     {
      77           25797 :         auto impl = std::make_shared<Impl>(static_cast<Derived&>(*this));
      78           25797 :         auto* raw = impl.get();
      79                 : 
      80                 :         {
      81           25797 :             std::lock_guard lock(state_->mutex_);
      82           25797 :             state_->impl_ptrs_.emplace(raw, std::move(impl));
      83           25797 :             state_->impl_list_.push_back(raw);
      84           25797 :         }
      85                 : 
      86           25797 :         return raw;
      87           25797 :     }
      88                 : 
      89           25797 :     void destroy(io_object::implementation* impl) override
      90                 :     {
      91           25797 :         auto* typed = static_cast<Impl*>(impl);
      92           25797 :         static_cast<Derived*>(this)->pre_destroy(typed);
      93           25797 :         typed->close_socket();
      94           25797 :         std::lock_guard lock(state_->mutex_);
      95           25797 :         state_->impl_list_.remove(typed);
      96           25797 :         state_->impl_ptrs_.erase(typed);
      97           25797 :     }
      98                 : 
      99           43007 :     void close(io_object::handle& h) override
     100                 :     {
     101           43007 :         static_cast<Impl*>(h.get())->close_socket();
     102           43007 :     }
     103                 : 
     104          443865 :     Scheduler& scheduler() const noexcept
     105                 :     {
     106          443865 :         return state_->sched_;
     107                 :     }
     108                 : 
     109           81457 :     void post(scheduler_op* op)
     110                 :     {
     111           81457 :         state_->sched_.post(op);
     112           81457 :     }
     113                 : 
     114            8915 :     void work_started() noexcept
     115                 :     {
     116            8915 :         state_->sched_.work_started();
     117            8915 :     }
     118                 : 
     119             299 :     void work_finished() noexcept
     120                 :     {
     121             299 :         state_->sched_.work_finished();
     122             299 :     }
     123                 : 
     124                 : protected:
     125                 :     // Override in derived to add pre-close logic (e.g. kqueue linger reset)
     126 MIS           0 :     void pre_shutdown(Impl*) noexcept {}
     127 HIT         154 :     void pre_destroy(Impl*) noexcept {}
     128                 : 
     129                 :     std::unique_ptr<state_type> state_;
     130                 : 
     131                 : private:
     132                 :     reactor_socket_service(reactor_socket_service const&)            = delete;
     133                 :     reactor_socket_service& operator=(reactor_socket_service const&) = delete;
     134                 : };
     135                 : 
     136                 : } // namespace boost::corosio::detail
     137                 : 
     138                 : #endif // BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_SOCKET_SERVICE_HPP
        

Generated by: LCOV version 2.3