LCOV - code coverage report
Current view: top level - corosio/io - io_signal_set.hpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 95.2 % 21 20 1
Test Date: 2026-02-17 21:42:07 Functions: 100.0 % 9 9

           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/io/io_object.hpp>
      15                 : #include <boost/capy/io_result.hpp>
      16                 : #include <boost/capy/error.hpp>
      17                 : #include <boost/capy/ex/executor_ref.hpp>
      18                 : #include <boost/capy/ex/io_env.hpp>
      19                 : 
      20                 : #include <coroutine>
      21                 : #include <stop_token>
      22                 : #include <system_error>
      23                 : 
      24                 : namespace boost::corosio {
      25                 : 
      26                 : /** Abstract base for asynchronous signal sets.
      27                 : 
      28                 :     Provides the common signal set interface: `wait` and `cancel`.
      29                 :     Concrete classes like @ref signal_set add signal registration
      30                 :     (add, remove, clear) and platform-specific flags.
      31                 : 
      32                 :     @par Thread Safety
      33                 :     Distinct objects: Safe.
      34                 :     Shared objects: Unsafe.
      35                 : 
      36                 :     @see signal_set, io_object
      37                 : */
      38                 : class BOOST_COROSIO_DECL io_signal_set : public io_object
      39                 : {
      40                 :     struct wait_awaitable
      41                 :     {
      42                 :         io_signal_set& s_;
      43                 :         std::stop_token token_;
      44                 :         mutable std::error_code ec_;
      45                 :         mutable int signal_number_ = 0;
      46                 : 
      47 HIT          26 :         explicit wait_awaitable(io_signal_set& s) noexcept : s_(s) {}
      48                 : 
      49              26 :         bool await_ready() const noexcept
      50                 :         {
      51              26 :             return token_.stop_requested();
      52                 :         }
      53                 : 
      54              26 :         capy::io_result<int> await_resume() const noexcept
      55                 :         {
      56              26 :             if (token_.stop_requested())
      57 MIS           0 :                 return {capy::error::canceled};
      58 HIT          26 :             return {ec_, signal_number_};
      59                 :         }
      60                 : 
      61              26 :         auto await_suspend(std::coroutine_handle<> h, capy::io_env const* env)
      62                 :             -> std::coroutine_handle<>
      63                 :         {
      64              26 :             token_ = env->stop_token;
      65              78 :             return s_.get().wait(
      66              78 :                 h, env->executor, token_, &ec_, &signal_number_);
      67                 :         }
      68                 :     };
      69                 : 
      70                 : public:
      71                 :     struct implementation : io_object::implementation
      72                 :     {
      73                 :         virtual std::coroutine_handle<> wait(
      74                 :             std::coroutine_handle<>,
      75                 :             capy::executor_ref,
      76                 :             std::stop_token,
      77                 :             std::error_code*,
      78                 :             int*) = 0;
      79                 : 
      80                 :         virtual void cancel() = 0;
      81                 :     };
      82                 : 
      83                 :     /** Cancel all operations associated with the signal set.
      84                 : 
      85                 :         Forces the completion of any pending asynchronous wait
      86                 :         operations. Each cancelled operation completes with an error
      87                 :         code that compares equal to `capy::cond::canceled`.
      88                 : 
      89                 :         Cancellation does not alter the set of registered signals.
      90                 :     */
      91              12 :     void cancel()
      92                 :     {
      93              12 :         do_cancel();
      94              12 :     }
      95                 : 
      96                 :     /** Wait for a signal to be delivered.
      97                 : 
      98                 :         The operation supports cancellation via `std::stop_token` through
      99                 :         the affine awaitable protocol. If the associated stop token is
     100                 :         triggered, the operation completes immediately with an error
     101                 :         that compares equal to `capy::cond::canceled`.
     102                 : 
     103                 :         @return An awaitable that completes with `io_result<int>`.
     104                 :             Returns the signal number when a signal is delivered,
     105                 :             or an error code on failure.
     106                 :     */
     107              26 :     auto wait()
     108                 :     {
     109              26 :         return wait_awaitable(*this);
     110                 :     }
     111                 : 
     112                 : protected:
     113                 :     /** Dispatch cancel to the concrete implementation. */
     114                 :     virtual void do_cancel() = 0;
     115                 : 
     116              88 :     explicit io_signal_set(handle h) noexcept : io_object(std::move(h)) {}
     117                 : 
     118                 :     /// Move construct.
     119               2 :     io_signal_set(io_signal_set&& other) noexcept : io_object(std::move(other))
     120                 :     {
     121               2 :     }
     122                 : 
     123                 :     /// Move assign.
     124                 :     io_signal_set& operator=(io_signal_set&& other) noexcept
     125                 :     {
     126                 :         if (this != &other)
     127                 :             h_ = std::move(other.h_);
     128                 :         return *this;
     129                 :     }
     130                 : 
     131                 :     io_signal_set(io_signal_set const&)            = delete;
     132                 :     io_signal_set& operator=(io_signal_set const&) = delete;
     133                 : 
     134                 : private:
     135              26 :     implementation& get() const noexcept
     136                 :     {
     137              26 :         return *static_cast<implementation*>(h_.get());
     138                 :     }
     139                 : };
     140                 : 
     141                 : } // namespace boost::corosio
     142                 : 
     143                 : #endif
        

Generated by: LCOV version 2.3