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

Generated by: LCOV version 2.3