LCOV - code coverage report
Current view: top level - boost/capy/ex - thread_pool.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 15 15
Test Date: 2026-01-15 20:40:20 Functions: 100.0 % 6 6

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
       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/boostorg/capy
       8              : //
       9              : 
      10              : #ifndef BOOST_CAPY_EX_THREAD_POOL_HPP
      11              : #define BOOST_CAPY_EX_THREAD_POOL_HPP
      12              : 
      13              : #include <boost/capy/detail/config.hpp>
      14              : #include <boost/capy/ex/any_coro.hpp>
      15              : #include <boost/capy/ex/execution_context.hpp>
      16              : #include <cstddef>
      17              : 
      18              : namespace boost {
      19              : namespace capy {
      20              : 
      21              : /** A thread pool execution context for running work asynchronously.
      22              : 
      23              :     This class provides a pool of worker threads that execute
      24              :     submitted work items. It inherits from `execution_context`,
      25              :     providing service management and a nested `executor_type`
      26              :     that satisfies the `capy::executor` concept.
      27              : 
      28              :     Work is submitted via the executor obtained from `get_executor()`.
      29              :     The executor's `post()`, `dispatch()`, and `defer()` functions
      30              :     queue coroutines for execution on pool threads.
      31              : 
      32              :     @par Thread Safety
      33              :     All member functions may be called concurrently.
      34              : 
      35              :     @par Example
      36              :     @code
      37              :     thread_pool pool(4);  // 4 worker threads
      38              :     auto ex = pool.get_executor();
      39              : 
      40              :     // Post a coroutine for execution
      41              :     ex.post(my_coroutine_handle);
      42              :     @endcode
      43              : 
      44              :     @see execution_context, executor
      45              : */
      46              : class BOOST_CAPY_DECL
      47              :     thread_pool
      48              :     : public execution_context
      49              : {
      50              :     class impl;
      51              :     impl* impl_;
      52              : 
      53              : public:
      54              :     class executor_type;
      55              : 
      56              :     /** Destructor.
      57              : 
      58              :         Signals all threads to stop and waits for them to complete.
      59              :         Calls `shutdown()` and `destroy()` to clean up services.
      60              :     */
      61              :     ~thread_pool();
      62              : 
      63              :     /** Construct a thread pool.
      64              : 
      65              :         @param num_threads The number of worker threads to create.
      66              :         If zero, defaults to the hardware concurrency.
      67              :     */
      68              :     explicit
      69              :     thread_pool(std::size_t num_threads = 0);
      70              : 
      71              :     thread_pool(thread_pool const&) = delete;
      72              :     thread_pool& operator=(thread_pool const&) = delete;
      73              : 
      74              :     /** Return an executor for this thread pool.
      75              : 
      76              :         The returned executor can be used to post work items
      77              :         to this thread pool.
      78              : 
      79              :         @return An executor associated with this thread pool.
      80              :     */
      81              :     executor_type
      82              :     get_executor() const noexcept;
      83              : };
      84              : 
      85              : //------------------------------------------------------------------------------
      86              : 
      87              : /** An executor for dispatching work to a thread_pool.
      88              : 
      89              :     The executor provides the interface for posting work items
      90              :     to the associated thread_pool. It satisfies the `capy::executor`
      91              :     concept.
      92              : 
      93              :     Executors are lightweight handles that can be copied and compared
      94              :     for equality. Two executors compare equal if they refer to the
      95              :     same thread_pool.
      96              : 
      97              :     @par Thread Safety
      98              :     Distinct objects: Safe.@n
      99              :     Shared objects: Safe.
     100              : */
     101              : class thread_pool::executor_type
     102              : {
     103              :     friend class thread_pool;
     104              : 
     105              :     thread_pool* pool_ = nullptr;
     106              : 
     107              :     explicit
     108           11 :     executor_type(thread_pool& pool) noexcept
     109           11 :         : pool_(&pool)
     110              :     {
     111           11 :     }
     112              : 
     113              : public:
     114              :     /** Default constructor.
     115              : 
     116              :         Constructs an executor not associated with any thread_pool.
     117              :     */
     118              :     executor_type() = default;
     119              : 
     120              :     /** Return a reference to the associated execution context.
     121              : 
     122              :         @return Reference to the thread_pool.
     123              :     */
     124              :     thread_pool&
     125            1 :     context() const noexcept
     126              :     {
     127            1 :         return *pool_;
     128              :     }
     129              : 
     130              :     /** Informs the executor that work is beginning.
     131              : 
     132              :         Must be paired with `on_work_finished()`.
     133              :     */
     134              :     BOOST_CAPY_DECL
     135              :     void
     136              :     on_work_started() const noexcept;
     137              : 
     138              :     /** Informs the executor that work has completed.
     139              : 
     140              :         @par Preconditions
     141              :         A preceding call to `on_work_started()` on an equal executor.
     142              :     */
     143              :     BOOST_CAPY_DECL
     144              :     void
     145              :     on_work_finished() const noexcept;
     146              : 
     147              :     /** Dispatch a coroutine handle.
     148              : 
     149              :         For thread_pool, dispatch always posts the work since
     150              :         the calling thread is never "inside" the pool's run loop.
     151              : 
     152              :         @param h The coroutine handle to dispatch.
     153              : 
     154              :         @return `std::noop_coroutine()` since work is always posted.
     155              :     */
     156              :     any_coro
     157            1 :     dispatch(any_coro h) const
     158              :     {
     159            1 :         post(h);
     160            1 :         return std::noop_coroutine();
     161              :     }
     162              : 
     163              :     /** Post a coroutine for deferred execution.
     164              : 
     165              :         The coroutine will be resumed on one of the pool's
     166              :         worker threads.
     167              : 
     168              :         @param h The coroutine handle to post.
     169              :     */
     170              :     BOOST_CAPY_DECL
     171              :     void
     172              :     post(any_coro h) const;
     173              : 
     174              :     /** Queue a coroutine for deferred execution.
     175              : 
     176              :         This is semantically identical to `post`, but conveys that
     177              :         `h` is a continuation of the current call context.
     178              : 
     179              :         @param h The coroutine handle to defer.
     180              :     */
     181              :     void
     182            1 :     defer(any_coro h) const
     183              :     {
     184            1 :         post(h);
     185            1 :     }
     186              : 
     187              :     /** Compare two executors for equality.
     188              : 
     189              :         @return `true` if both executors refer to the same thread_pool.
     190              :     */
     191              :     bool
     192            3 :     operator==(executor_type const& other) const noexcept
     193              :     {
     194            3 :         return pool_ == other.pool_;
     195              :     }
     196              : };
     197              : 
     198              : //------------------------------------------------------------------------------
     199              : 
     200              : inline
     201              : auto
     202           11 : thread_pool::
     203              : get_executor() const noexcept ->
     204              :     executor_type
     205              : {
     206           11 :     return executor_type(const_cast<thread_pool&>(*this));
     207              : }
     208              : 
     209              : } // capy
     210              : } // boost
     211              : 
     212              : #endif
        

Generated by: LCOV version 2.3