userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
single_use_event.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/engine/single_use_event.hpp
4
/// @brief @copybrief engine::SingleUseEvent
5
6
#
include
<
userver
/
compiler
/
impl
/
lifetime
.
hpp
>
7
#
include
<
userver
/
engine
/
awaitable
.
hpp
>
8
#
include
<
userver
/
engine
/
deadline
.
hpp
>
9
#
include
<
userver
/
engine
/
future_status
.
hpp
>
10
#
include
<
userver
/
engine
/
impl
/
context_accessor
.
hpp
>
11
#
include
<
userver
/
engine
/
impl
/
wait_list_fwd
.
hpp
>
12
#
include
<
userver
/
utils
/
fast_pimpl
.
hpp
>
13
#
include
<
userver
/
utils
/
impl
/
internal_tag
.
hpp
>
14
15
USERVER_NAMESPACE_BEGIN
16
17
namespace
engine {
18
19
/// @ingroup userver_concurrency
20
///
21
/// @brief A single-producer, single-consumer event.
22
///
23
/// Once the producer sends the event, it remains in the signaled state forever.
24
///
25
/// SingleUseEvent can be used as a faster non-allocating alternative
26
/// to engine::Future. However, it is more low-level and error-prone, see below.
27
///
28
/// Compatible with engine::WaitAny and friends.
29
///
30
/// ## Destroying a SingleUseEvent after waking up
31
///
32
/// The waiting task is allowed to immediately destroy the `SingleUseEvent`
33
/// after waking up; it will not stop a concurrent `Send` from completing
34
/// correctly. This is contrary to the properties of other userver
35
/// synchronization primitives, like engine::Mutex.
36
///
37
/// However, if the wait operation ends in something other than
38
/// engine::Future::kReady, then it is the responsibility of the awaiter
39
/// to guarantee that it either prevents the oncoming `Send` call or awaits it.
40
/// One way to force waiting until the `Send` call happens is to use
41
/// engine::SingleUseEvent::WaitNonCancellable.
42
///
43
/// ## Example usage
44
///
45
/// @snippet engine/single_use_event_test.cpp Wait and destroy
46
///
47
/// @see @ref scripts/docs/en/userver/synchronization.md
48
class
SingleUseEvent
final
:
private
impl
::AwaitableBase {
49
public
:
50
SingleUseEvent()
noexcept
;
51
52
SingleUseEvent(
const
SingleUseEvent&) =
delete
;
53
SingleUseEvent(SingleUseEvent&&) =
delete
;
54
SingleUseEvent& operator=(
const
SingleUseEvent&) =
delete
;
55
SingleUseEvent& operator=(SingleUseEvent&&) =
delete
;
56
~SingleUseEvent();
57
58
/// @brief Waits until the event is in a signaled state.
59
///
60
/// @throws engine::WaitInterruptedException if the current task is cancelled
61
void
Wait
();
62
63
/// @brief Waits until the event is in a signaled state, or the deadline
64
/// expires, or the current task is cancelled.
65
[[nodiscard]]
FutureStatus
WaitUntil
(Deadline);
66
67
/// @brief Waits until the event is in a signaled state, ignoring task
68
/// cancellations.
69
///
70
/// The awaiter task can destroy the `SingleUseEvent` object immediately
71
/// after waking up, if necessary.
72
void
WaitNonCancellable
()
noexcept
;
73
74
/// Sets the signal flag and wakes a task that waits on it, if any.
75
/// `Send` must not be called again.
76
///
77
/// You can safely invoke Send from outside a coroutine.
78
void
Send
()
noexcept
;
79
80
/// Returns true iff already signaled.
81
[[nodiscard]]
bool
IsReady
()
const
noexcept
override
;
82
83
/// Satisfies @ref engine::Awaitable, for use with @ref engine::WaitAnyContext and friends.
84
AwaitableToken
GetAwaitableToken
()
noexcept
USERVER_IMPL_LIFETIME_BOUND {
85
return
AwaitableToken{
utils
::impl::InternalTag{},
this
};
86
}
87
88
private
:
89
void
TryAppendAwaiter(
impl
::AwaiterPtr& awaiter, std::uintptr_t context)
override
;
90
impl
::AwaiterPtr RemoveAwaiter(
impl
::Awaiter& awaiter, std::uintptr_t context)
noexcept
override
;
91
92
impl
::FastPimplWaitListLight awaiters_;
93
};
94
95
}
// namespace engine
96
97
USERVER_NAMESPACE_END
userver
engine
single_use_event.hpp
Generated on
for userver by
Doxygen
1.17.0