LCOV - code coverage report
Current view: top level - corosio/native - native_io_context.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 45 45
Test Date: 2026-06-02 22:30:31 Functions: 100.0 % 24 24

           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_NATIVE_IO_CONTEXT_HPP
      11                 : #define BOOST_COROSIO_NATIVE_NATIVE_IO_CONTEXT_HPP
      12                 : 
      13                 : #include <boost/corosio/io_context.hpp>
      14                 : #include <boost/corosio/backend.hpp>
      15                 : 
      16                 : #ifndef BOOST_COROSIO_MRDOCS
      17                 : #if BOOST_COROSIO_HAS_EPOLL
      18                 : #include <boost/corosio/native/detail/epoll/epoll_scheduler.hpp>
      19                 : #endif
      20                 : 
      21                 : #if BOOST_COROSIO_HAS_SELECT
      22                 : #include <boost/corosio/native/detail/select/select_scheduler.hpp>
      23                 : #endif
      24                 : 
      25                 : #if BOOST_COROSIO_HAS_KQUEUE
      26                 : #include <boost/corosio/native/detail/kqueue/kqueue_scheduler.hpp>
      27                 : #endif
      28                 : 
      29                 : #if BOOST_COROSIO_HAS_IOCP
      30                 : #include <boost/corosio/native/detail/iocp/win_scheduler.hpp>
      31                 : #endif
      32                 : 
      33                 : #if BOOST_COROSIO_HAS_IO_URING
      34                 : #include <boost/corosio/native/detail/io_uring/io_uring_scheduler.hpp>
      35                 : #endif
      36                 : #endif // !BOOST_COROSIO_MRDOCS
      37                 : 
      38                 : namespace boost::corosio {
      39                 : 
      40                 : /** An I/O context with devirtualized event loop methods.
      41                 : 
      42                 :     This class template inherits from @ref io_context and shadows
      43                 :     all public methods with versions that call the concrete
      44                 :     scheduler directly, bypassing virtual dispatch. No new state
      45                 :     is added.
      46                 : 
      47                 :     A `native_io_context` IS-A `io_context` and can be passed
      48                 :     anywhere an `io_context&` is accepted, in which case virtual
      49                 :     dispatch is used transparently.
      50                 : 
      51                 :     @tparam Backend A backend tag value (e.g., `epoll`,
      52                 :         `iocp`) whose type provides `scheduler_type`.
      53                 : 
      54                 :     @par Thread Safety
      55                 :     Same as the underlying context type.
      56                 : 
      57                 :     @par Example
      58                 :     @code
      59                 :     #include <boost/corosio/native/native_io_context.hpp>
      60                 : 
      61                 :     native_io_context<epoll> ctx;
      62                 :     ctx.poll();  // devirtualized call
      63                 :     @endcode
      64                 : 
      65                 :     @see io_context, epoll_t, iocp_t
      66                 : */
      67                 : template<auto Backend>
      68                 : class native_io_context : public io_context
      69                 : {
      70                 :     using backend_type   = decltype(Backend);
      71                 :     using scheduler_type = typename backend_type::scheduler_type;
      72                 : 
      73 HIT          42 :     scheduler_type& sched() noexcept
      74                 :     {
      75              42 :         return *static_cast<scheduler_type*>(this->sched_);
      76                 :     }
      77                 : 
      78                 : public:
      79                 :     /** Construct with default concurrency. */
      80              18 :     native_io_context() : io_context(Backend) {}
      81                 : 
      82                 :     /** Construct with a concurrency hint.
      83                 : 
      84                 :         @param concurrency_hint Hint for the number of threads that
      85                 :             will call `run()`.
      86                 :     */
      87               2 :     explicit native_io_context(unsigned concurrency_hint)
      88               2 :         : io_context(Backend, concurrency_hint)
      89                 :     {
      90               2 :     }
      91                 : 
      92                 :     /** Construct with runtime tuning options.
      93                 : 
      94                 :         @param opts Runtime options controlling scheduler and
      95                 :             service behavior.
      96                 :         @param concurrency_hint Hint for the number of threads that
      97                 :             will call `run()`.
      98                 :     */
      99               2 :     explicit native_io_context(
     100                 :         io_context_options const& opts,
     101                 :         unsigned concurrency_hint = std::thread::hardware_concurrency())
     102               2 :         : io_context(Backend, opts, concurrency_hint)
     103                 :     {
     104               2 :     }
     105                 : 
     106                 :     // Non-copyable, non-movable
     107                 :     native_io_context(native_io_context const&)            = delete;
     108                 :     native_io_context& operator=(native_io_context const&) = delete;
     109                 : 
     110                 :     /// Signal the context to stop processing.
     111               2 :     void stop()
     112                 :     {
     113               2 :         sched().stop();
     114               2 :     }
     115                 : 
     116                 :     /// Return whether the context has been stopped.
     117              22 :     bool stopped() const noexcept
     118                 :     {
     119              22 :         return const_cast<native_io_context*>(this)->sched().stopped();
     120                 :     }
     121                 : 
     122                 :     /// Restart the context after being stopped.
     123               2 :     void restart()
     124                 :     {
     125               2 :         sched().restart();
     126               2 :     }
     127                 : 
     128                 :     /** Process all pending work items.
     129                 : 
     130                 :         @return The number of handlers executed.
     131                 :     */
     132               2 :     std::size_t run()
     133                 :     {
     134               2 :         return sched().run();
     135                 :     }
     136                 : 
     137                 :     /** Process at most one pending work item.
     138                 : 
     139                 :         @return The number of handlers executed (0 or 1).
     140                 :     */
     141                 :     std::size_t run_one()
     142                 :     {
     143                 :         return sched().run_one();
     144                 :     }
     145                 : 
     146                 :     /** Process work items for the specified duration.
     147                 : 
     148                 :         @param rel_time The duration for which to process work.
     149                 : 
     150                 :         @return The number of handlers executed.
     151                 :     */
     152                 :     template<class Rep, class Period>
     153               4 :     std::size_t run_for(std::chrono::duration<Rep, Period> const& rel_time)
     154                 :     {
     155               4 :         return run_until(std::chrono::steady_clock::now() + rel_time);
     156                 :     }
     157                 : 
     158                 :     /** Process work items until the specified time.
     159                 : 
     160                 :         @param abs_time The time point until which to process work.
     161                 : 
     162                 :         @return The number of handlers executed.
     163                 :     */
     164                 :     template<class Clock, class Duration>
     165                 :     std::size_t
     166               4 :     run_until(std::chrono::time_point<Clock, Duration> const& abs_time)
     167                 :     {
     168               4 :         std::size_t n = 0;
     169               6 :         while (run_one_until(abs_time))
     170               2 :             if (n != (std::numeric_limits<std::size_t>::max)())
     171               2 :                 ++n;
     172               4 :         return n;
     173                 :     }
     174                 : 
     175                 :     /** Process at most one work item for the specified duration.
     176                 : 
     177                 :         @param rel_time The duration for which the call may block.
     178                 : 
     179                 :         @return The number of handlers executed (0 or 1).
     180                 :     */
     181                 :     template<class Rep, class Period>
     182                 :     std::size_t run_one_for(std::chrono::duration<Rep, Period> const& rel_time)
     183                 :     {
     184                 :         return run_one_until(std::chrono::steady_clock::now() + rel_time);
     185                 :     }
     186                 : 
     187                 :     /** Process at most one work item until the specified time.
     188                 : 
     189                 :         @param abs_time The time point until which the call may block.
     190                 : 
     191                 :         @return The number of handlers executed (0 or 1).
     192                 :     */
     193                 :     template<class Clock, class Duration>
     194                 :     std::size_t
     195              10 :     run_one_until(std::chrono::time_point<Clock, Duration> const& abs_time)
     196                 :     {
     197              10 :         typename Clock::time_point now = Clock::now();
     198               2 :         for (;;)
     199                 :         {
     200              12 :             auto rel_time = abs_time - now;
     201                 :             using rel_type = decltype(rel_time);
     202              12 :             if (rel_time < rel_type::zero())
     203               2 :                 rel_time = rel_type::zero();
     204              10 :             else if (rel_time > std::chrono::seconds(1))
     205               2 :                 rel_time = std::chrono::seconds(1);
     206                 : 
     207              24 :             std::size_t s = sched().wait_one(
     208                 :                 static_cast<long>(
     209              12 :                     std::chrono::duration_cast<std::chrono::microseconds>(
     210                 :                         rel_time)
     211              12 :                         .count()));
     212                 : 
     213              12 :             if (s || stopped())
     214              10 :                 return s;
     215                 : 
     216               4 :             now = Clock::now();
     217               4 :             if (now >= abs_time)
     218               2 :                 return 0;
     219                 :         }
     220                 :     }
     221                 : 
     222                 :     /** Process all ready work items without blocking.
     223                 : 
     224                 :         @return The number of handlers executed.
     225                 :     */
     226               2 :     std::size_t poll()
     227                 :     {
     228               2 :         return sched().poll();
     229                 :     }
     230                 : 
     231                 :     /** Process at most one ready work item without blocking.
     232                 : 
     233                 :         @return The number of handlers executed (0 or 1).
     234                 :     */
     235                 :     std::size_t poll_one()
     236                 :     {
     237                 :         return sched().poll_one();
     238                 :     }
     239                 : };
     240                 : 
     241                 : } // namespace boost::corosio
     242                 : 
     243                 : #endif // BOOST_COROSIO_NATIVE_NATIVE_IO_CONTEXT_HPP
        

Generated by: LCOV version 2.3