LCOV - code coverage report
Current view: top level - corosio/native/detail/reactor - reactor_signal_pipe.hpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 95.0 % 20 19 1
Test Date: 2026-10-17 04:01:32 Functions: 75.0 % 4 3 1

           TLA  Line data    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_SIGNAL_PIPE_HPP
      11                 : #define BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_SIGNAL_PIPE_HPP
      12                 : 
      13                 : #include <boost/corosio/detail/platform.hpp>
      14                 : 
      15                 : #if BOOST_COROSIO_POSIX
      16                 : 
      17                 : #include <boost/corosio/native/detail/posix/posix_signal_service.hpp>
      18                 : #include <boost/corosio/native/detail/reactor/reactor_descriptor_state.hpp>
      19                 : #include <boost/corosio/native/detail/reactor/reactor_op_base.hpp>
      20                 : 
      21                 : #include <errno.h>
      22                 : 
      23                 : /*
      24                 :     Reactor signal-pipe reader
      25                 :     ==========================
      26                 : 
      27                 :     Bridges the global POSIX signal self-pipe (see posix_signal_service.hpp)
      28                 :     to the reactor backends (epoll/kqueue/select). The concrete scheduler owns
      29                 :     one of these for its lifetime and, in register_signal_reader(), parks the
      30                 :     drain op as the descriptor's read_op then calls register_descriptor().
      31                 : 
      32                 :     On each read-readiness edge the drain op completes without touching the
      33                 :     pipe, and invoke_deferred_io runs it once the descriptor lock is
      34                 :     released. Only then does it drain the pipe and deliver the signals:
      35                 :     delivery posts into every context watching the pipe, and a post made
      36                 :     under this descriptor's lock would order it before another context's
      37                 :     scheduler lock, the reverse of that scheduler's own order. The op then
      38                 :     parks itself again, draining once more if an edge arrived meanwhile.
      39                 : */
      40                 : 
      41                 : namespace boost::corosio::detail {
      42                 : 
      43                 : struct reactor_signal_pipe_reader
      44                 : {
      45                 :     struct drain_op final : reactor_op_base
      46                 :     {
      47                 :         reactor_signal_pipe_reader* reader = nullptr;
      48                 : 
      49 HIT         940 :         void perform_io() noexcept override
      50                 :         {
      51             940 :             errn = 0;
      52             940 :         }
      53                 : 
      54             940 :         void operator()() override
      55                 :         {
      56             940 :             auto& desc = reader->desc;
      57                 :             for (;;)
      58                 :             {
      59             941 :                 posix_signal_detail::drain_signal_pipe();
      60             941 :                 conditionally_enabled_mutex::scoped_lock lock(desc.mutex);
      61                 :                 // An edge seen while unparked set read_ready instead.
      62             941 :                 if (!desc.read_ready)
      63                 :                 {
      64             940 :                     desc.read_op = this;
      65             940 :                     break;
      66                 :                 }
      67               1 :                 desc.read_ready = false;
      68             942 :             }
      69                 :             // A select() started while this op was out ran without the
      70                 :             // pipe in its read set.
      71             940 :             desc.scheduler_->notify_reparked();
      72                 :             // Nothing counted this op as work; balance the decrement
      73                 :             // that follows the inline run of a completed op.
      74             940 :             desc.scheduler_->compensating_work_started();
      75             940 :         }
      76                 : 
      77 MIS           0 :         void destroy() override {}
      78                 :     };
      79                 : 
      80                 :     reactor_descriptor_state desc;
      81                 :     drain_op op;
      82                 : 
      83                 :     // Park the drain op and return the descriptor to hand to
      84                 :     // scheduler::register_descriptor(read_fd, ...).
      85 HIT         555 :     reactor_descriptor_state* arm() noexcept
      86                 :     {
      87             555 :         op.reader    = this;
      88             555 :         desc.read_op = &op;
      89             555 :         return &desc;
      90                 :     }
      91                 : };
      92                 : 
      93                 : } // namespace boost::corosio::detail
      94                 : 
      95                 : #endif // BOOST_COROSIO_POSIX
      96                 : 
      97                 : #endif // BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_SIGNAL_PIPE_HPP
        

Generated by: LCOV version 2.3