Lightweight
0.20260617.0
Loading...
Searching...
No Matches
ThreadPoolExecutor.hpp
1
// SPDX-License-Identifier: Apache-2.0
2
#pragma once
3
4
#include "../Api.hpp"
5
#include "Executor.hpp"
6
7
#include <cstddef>
8
#include <memory>
9
10
namespace
Lightweight::Async
11
{
12
13
/// A fixed-size pool of worker threads that run posted work concurrently.
14
///
15
/// This is the default "DB worker" offload target: blocking ODBC calls are posted here and
16
/// executed on a worker thread while the awaiting coroutine is suspended. The pool is built on
17
/// stdexec's @c exec::static_thread_pool (the C++26 @c std::execution scheduler model); each posted
18
/// @c Work item is spawned as a @c schedule|then sender into an @c exec::async_scope so the
19
/// destructor can wait for every in-flight item to finish, draining and joining. The pool must
20
/// therefore outlive every coroutine that can resume on it.
21
///
22
/// The stdexec machinery lives in a pimpl defined in the translation unit, so this public header
23
/// pulls in no stdexec headers — keeping them out of the C++20 module's global module fragment and
24
/// off every downstream consumer that does not opt in.
25
class
LIGHTWEIGHT_API
ThreadPoolExecutor
final:
public
IExecutor
,
public
IResumeScheduler
26
{
27
public
:
28
/// Constructs the pool and starts @p threadCount worker threads.
29
///
30
/// @param threadCount Number of worker threads to start (must be >= 1).
31
/// @throws std::invalid_argument if @p threadCount is 0 or exceeds the supported maximum
32
/// (@c std::uint32_t, the width the underlying stdexec pool accepts).
33
explicit
ThreadPoolExecutor
(std::size_t threadCount);
34
35
ThreadPoolExecutor
(
ThreadPoolExecutor
const
&) =
delete
;
36
ThreadPoolExecutor
& operator=(
ThreadPoolExecutor
const
&) =
delete
;
37
ThreadPoolExecutor
(
ThreadPoolExecutor
&&) =
delete
;
38
ThreadPoolExecutor
& operator=(
ThreadPoolExecutor
&&) =
delete
;
39
40
/// Waits for all in-flight work to drain, then stops and joins the worker threads.
41
///
42
/// @note Must not be invoked from one of this pool's own worker threads (i.e. the pool must
43
/// outlive every coroutine that can resume on it). The drain blocks the calling thread,
44
/// so destroying the pool from a thread it owns would deadlock — the same constraint the
45
/// previous join-based teardown had.
46
~ThreadPoolExecutor
()
override
;
47
48
void
Post
(Work work)
override
;
49
void
Resume
(std::coroutine_handle<> handle)
override
;
50
51
/// @return the configured worker count (the value passed to the constructor).
52
/// @note This is the requested count, not a live count of OS threads; it is fixed for the
53
/// pool's lifetime and does not reflect any internal clamping the scheduler might apply.
54
[[nodiscard]] std::size_t
ThreadCount
() const noexcept
55
{
56
return
_threadCount;
57
}
58
59
private
:
60
/// Holds the stdexec @c static_thread_pool and @c async_scope; defined in the .cpp so the
61
/// stdexec headers never reach this public header (nor the module's global module fragment).
62
struct
Impl;
63
64
std::size_t _threadCount;
///< Configured worker count (exposed via ThreadCount()).
65
std::unique_ptr<Impl> _impl;
///< stdexec pool + scope; destroyed (and drained) in ~ThreadPoolExecutor.
66
};
67
68
}
// namespace Lightweight::Async
Lightweight::Async::IExecutor
Definition
Executor.hpp:22
Lightweight::Async::IResumeScheduler
Definition
Executor.hpp:43
Lightweight::Async::ThreadPoolExecutor
Definition
ThreadPoolExecutor.hpp:26
Lightweight::Async::ThreadPoolExecutor::Resume
void Resume(std::coroutine_handle<> handle) override
Lightweight::Async::ThreadPoolExecutor::ThreadPoolExecutor
ThreadPoolExecutor(std::size_t threadCount)
Lightweight::Async::ThreadPoolExecutor::ThreadCount
std::size_t ThreadCount() const noexcept
Definition
ThreadPoolExecutor.hpp:54
Lightweight::Async::ThreadPoolExecutor::~ThreadPoolExecutor
~ThreadPoolExecutor() override
Lightweight::Async::ThreadPoolExecutor::Post
void Post(Work work) override
Lightweight
Async
ThreadPoolExecutor.hpp
Generated by
1.9.8