Lightweight
0.20260921.0
Loading...
Searching...
No Matches
ManualExecutor.hpp
1
// SPDX-License-Identifier: Apache-2.0
2
#pragma once
3
4
#include "../Api.hpp"
5
#include "Executor.hpp"
6
#include "detail/ExecutorQueues.hpp"
7
8
#include <cstddef>
9
#include <stop_token>
10
11
namespace
Lightweight::Async
12
{
13
14
/// @ingroup Async
15
/// An executor that runs work only when explicitly pumped by the owning thread.
16
///
17
/// This is the "app thread" / event-loop resume target for the single-threaded model:
18
/// blocking ODBC work is offloaded to a @ref ThreadPoolExecutor, and the coroutine's
19
/// continuation is posted back here so that all user-visible coroutine logic resumes on the
20
/// one thread that drives this executor (via @ref Run, @ref Drain, @ref RunOne or
21
/// @ref RunUntil). All members are thread-safe to call; the pumping members
22
/// (@ref Run / @ref Drain / @ref RunOne / @ref RunUntil) are intended for a single
23
/// consumer thread.
24
class
LIGHTWEIGHT_API
ManualExecutor
final:
public
IExecutor
,
public
IResumeScheduler
25
{
26
public
:
27
ManualExecutor
() =
default
;
28
ManualExecutor
(
ManualExecutor
const
&) =
delete
;
29
ManualExecutor
& operator=(
ManualExecutor
const
&) =
delete
;
30
ManualExecutor
(
ManualExecutor
&&) =
delete
;
31
ManualExecutor
& operator=(
ManualExecutor
&&) =
delete
;
32
~ManualExecutor
()
override
=
default
;
33
34
void
Post
(Work work)
override
;
35
void
Resume
(std::coroutine_handle<> handle)
override
;
36
37
/// Runs at most one queued work item without blocking.
38
/// @return true if an item was run, false if the queue was empty.
39
bool
RunOne
();
40
41
/// Runs all currently-runnable work until the queue is empty, without blocking.
42
/// @return the number of work items executed.
43
std::size_t
Drain
();
44
45
/// Blocks pumping work until @ref Stop is called and the queue has drained.
46
void
Run
();
47
48
/// Requests @ref Run to return once the queue is empty.
49
void
Stop
();
50
51
/// @return the number of currently-queued work items.
52
[[nodiscard]] std::size_t
PendingCount
()
const
;
53
54
/// Pumps work until @p predicate returns true.
55
///
56
/// Blocks the calling thread between work items, waking when new work is posted. The
57
/// predicate must be cheap and must not acquire this executor's internal lock. This is
58
/// the driver used by @c SyncWaitPumping for the single-threaded model.
59
///
60
/// @tparam Predicate A callable returning something contextually convertible to bool.
61
/// @param predicate Stop condition, re-checked between work items.
62
template
<
typename
Predicate>
63
void
RunUntil
(Predicate predicate)
64
{
65
// NOTE: RunUntil deliberately ignores the stop request — it must pump strictly until the
66
// predicate is satisfied (the awaited task completes). Honoring Stop() here would return early
67
// with the predicate still false, causing the caller (SyncWaitPumping) to read an unfinished
68
// result. The stop request governs Run() (the event-loop pump), not RunUntil. The wake
69
// condition is the predicate alone; wakeups are delivered by the work posted to the queue.
70
while
(!predicate())
71
{
72
Work work;
73
if
(!_queue.WaitAndPop(work, predicate))
74
return
;
75
work();
76
}
77
}
78
79
private
:
80
detail::PumpQueue _queue;
81
std::stop_source _stopSource;
///< Requested by Stop(); read by Run()'s wake condition.
82
};
83
84
}
// namespace Lightweight::Async
Lightweight::Async::IExecutor
Definition
Executor.hpp:23
Lightweight::Async::IResumeScheduler
Definition
Executor.hpp:45
Lightweight::Async::ManualExecutor
Definition
ManualExecutor.hpp:25
Lightweight::Async::ManualExecutor::Post
void Post(Work work) override
Lightweight::Async::ManualExecutor::Drain
std::size_t Drain()
Lightweight::Async::ManualExecutor::PendingCount
std::size_t PendingCount() const
Lightweight::Async::ManualExecutor::RunOne
bool RunOne()
Lightweight::Async::ManualExecutor::Run
void Run()
Blocks pumping work until Stop is called and the queue has drained.
Lightweight::Async::ManualExecutor::Stop
void Stop()
Requests Run to return once the queue is empty.
Lightweight::Async::ManualExecutor::Resume
void Resume(std::coroutine_handle<> handle) override
Lightweight::Async::ManualExecutor::RunUntil
void RunUntil(Predicate predicate)
Definition
ManualExecutor.hpp:63
Lightweight
Async
ManualExecutor.hpp
Generated by
1.9.8