LCOV - code coverage report
Current view: top level - corosio/io - io_signal_set.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 13 13
Test Date: 2026-10-17 04:01:32 Functions: 100.0 % 7 7

           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_IO_IO_SIGNAL_SET_HPP
      11                 : #define BOOST_COROSIO_IO_IO_SIGNAL_SET_HPP
      12                 : 
      13                 : #include <boost/corosio/detail/config.hpp>
      14                 : #include <boost/corosio/detail/op_base.hpp>
      15                 : #include <boost/corosio/io/io_object.hpp>
      16                 : #include <boost/capy/results.hpp>
      17                 : #include <boost/capy/error.hpp>
      18                 : #include <boost/capy/ex/executor_ref.hpp>
      19                 : #include <boost/capy/ex/await_context.hpp>
      20                 : 
      21                 : #include <boost/capy/continuation.hpp>
      22                 : 
      23                 : #include <coroutine>
      24                 : #include <stop_token>
      25                 : #include <system_error>
      26                 : 
      27                 : namespace boost::corosio {
      28                 : 
      29                 : /** Delivers a registered signal to the waiting coroutine.
      30                 : 
      31                 :     Provides the common signal set interface: `wait` and `cancel`.
      32                 :     Concrete classes like @ref signal_set add signal registration
      33                 :     (add, remove, clear) and platform-specific flags.
      34                 : 
      35                 :     @par Thread Safety
      36                 :     Distinct objects: Safe.
      37                 :     Shared objects: Unsafe.
      38                 : 
      39                 :     @see signal_set, io_object
      40                 : */
      41                 : class BOOST_COROSIO_DECL io_signal_set : public io_object
      42                 : {
      43                 :     struct wait_awaitable : detail::value_op_base<wait_awaitable, int>
      44                 :     {
      45                 :     private:
      46                 :         friend io_signal_set;
      47                 :         friend detail::value_op_base<wait_awaitable, int>;
      48                 : 
      49                 :         io_signal_set& s_;
      50                 : 
      51 HIT      206016 :         explicit wait_awaitable(io_signal_set& s) noexcept : s_(s) {}
      52                 : 
      53                 :         std::coroutine_handle<>
      54          205987 :         dispatch(capy::continuation& cont, capy::executor_ref ex) const
      55                 :         {
      56          205987 :             return s_.get().wait(cont, ex, token_, &ec_, &value_);
      57                 :         }
      58                 :     };
      59                 : 
      60                 : public:
      61                 :     /** Define backend hooks for signal set wait and cancel.
      62                 : 
      63                 :         Platform backends derive from this to implement
      64                 :         signal delivery notification.
      65                 :     */
      66                 :     struct implementation : io_object::implementation
      67                 :     {
      68                 :         /** Initiate an asynchronous wait for a signal.
      69                 : 
      70                 :             @param cont Continuation to resume on completion; it lives in
      71                 :                 the awaiting frame until then.
      72                 :             @param ex Executor for dispatching the completion.
      73                 :             @param token Stop token for cancellation.
      74                 :             @param ec Output error code.
      75                 :             @param signo Output signal number.
      76                 : 
      77                 :             @return Coroutine handle to resume immediately.
      78                 :         */
      79                 :         virtual std::coroutine_handle<> wait(
      80                 :             capy::continuation& cont,
      81                 :             capy::executor_ref ex,
      82                 :             std::stop_token token,
      83                 :             std::error_code* ec,
      84                 :             int* signo) = 0;
      85                 : 
      86                 :         /** Cancel all pending wait operations.
      87                 : 
      88                 :             Cancelled waiters complete with an error that
      89                 :             compares equal to `capy::cond::canceled`.
      90                 :         */
      91                 :         virtual void cancel() noexcept = 0;
      92                 :     };
      93                 : 
      94                 :     /** Cancel all operations associated with the signal set.
      95                 : 
      96                 :         Forces the completion of any pending asynchronous wait
      97                 :         operations. Each cancelled operation completes with an error
      98                 :         code that compares equal to `capy::cond::canceled`.
      99                 : 
     100                 :         Cancellation does not alter the set of registered signals.
     101                 :     */
     102          200021 :     void cancel() noexcept
     103                 :     {
     104          200021 :         do_cancel();
     105          200021 :     }
     106                 : 
     107                 :     /** Wait for a signal to be delivered.
     108                 : 
     109                 :         The operation supports cancellation via `std::stop_token` through
     110                 :         the affine awaitable protocol. If the associated stop token is
     111                 :         triggered, the operation completes immediately with an error
     112                 :         that compares equal to `capy::cond::canceled`.
     113                 : 
     114                 :         This signal set must outlive the returned awaitable.
     115                 : 
     116                 :         @note On Windows a stop request resumes the awaiting coroutine
     117                 :             inline, on the thread that called `request_stop()`. On POSIX
     118                 :             it always resumes on a thread running the execution context.
     119                 : 
     120                 :         @return An awaitable that completes with `results<int>`.
     121                 :             Returns the signal number when a signal is delivered,
     122                 :             or an error code on failure.
     123                 :     */
     124          206016 :     [[nodiscard]] auto wait()
     125                 :     {
     126          206016 :         return wait_awaitable(*this);
     127                 :     }
     128                 : 
     129                 : protected:
     130                 :     /** Dispatch cancel to the concrete implementation. */
     131                 :     virtual void do_cancel() noexcept = 0;
     132                 : 
     133                 :     /** Adopt an existing handle.
     134                 : 
     135                 :         @param h The handle the signal set takes ownership of.
     136                 :     */
     137            3476 :     explicit io_signal_set(handle h) noexcept : io_object(std::move(h)) {}
     138                 : 
     139                 :     /// Move construct.
     140               4 :     io_signal_set(io_signal_set&& other) noexcept : io_object(std::move(other))
     141                 :     {
     142               4 :     }
     143                 : 
     144                 :     /// Move assign.
     145                 :     io_signal_set& operator=(io_signal_set&& other) noexcept
     146                 :     {
     147                 :         if (this != &other)
     148                 :             h_ = std::move(other.h_);
     149                 :         return *this;
     150                 :     }
     151                 : 
     152                 :     /// Copy construction is disabled; the handle is uniquely owned.
     153                 :     io_signal_set(io_signal_set const&) = delete;
     154                 :     /// Copy assignment is disabled; the handle is uniquely owned.
     155                 :     io_signal_set& operator=(io_signal_set const&) = delete;
     156                 : 
     157                 : private:
     158          205987 :     implementation& get() const noexcept
     159                 :     {
     160          205987 :         return *static_cast<implementation*>(h_.get());
     161                 :     }
     162                 : };
     163                 : 
     164                 : } // namespace boost::corosio
     165                 : 
     166                 : #endif
        

Generated by: LCOV version 2.3