userver: userver/engine/single_use_event.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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 <atomic>
7#include <cstdint>
8
9USERVER_NAMESPACE_BEGIN
10
11namespace engine {
12
13/// @ingroup userver_concurrency
14///
15/// @brief A single-producer, single-consumer event
16///
17/// Must not be awaited or signaled multiple times in the same waiting session.
18///
19/// The main advantage of `SingleUseEvent` over `SingleConsumerEvent` is that
20/// the waiting coroutine is allowed to immediately destroy the `SingleUseEvent`
21/// after waking up; it will not stop a concurrent `Send` from completing
22/// correctly.
23///
24/// Timeouts and cancellations are not supported. Only a concurrent call to
25/// `Send` can wake up the waiter. This is necessary for the waiter not to
26/// destroy the `SingleUseEvent` unexpectedly for the sender.
27///
28/// ## Example usage:
29///
30/// @snippet engine/single_use_event_test.cpp Wait and destroy
31///
32/// @see @ref scripts/docs/en/userver/synchronization.md
33class SingleUseEvent final {
34 public:
35 constexpr SingleUseEvent() noexcept : state_(0) {}
36 ~SingleUseEvent();
37
38 SingleUseEvent(const SingleUseEvent&) = delete;
39 SingleUseEvent(SingleUseEvent&&) = delete;
40 SingleUseEvent& operator=(const SingleUseEvent&) = delete;
41 SingleUseEvent& operator=(SingleUseEvent&&) = delete;
42
43 /// @brief Waits until the event is in a signaled state
44 ///
45 /// The event then remains in a signaled state, it does not reset
46 /// automatically.
47 ///
48 /// The waiter coroutine can destroy the `SingleUseEvent` object immediately
49 /// after waking up, if necessary.
50 void WaitNonCancellable() noexcept;
51
52 /// Sets the signal flag and wakes a coroutine that waits on it, if any.
53 /// `Send` must not be called again without `Reset`.
54 void Send() noexcept;
55
56 /// Resets the signal flag. Can be called after `WaitNonCancellable` returns
57 /// if necessary to reuse the `SingleUseEvent` for another waiting session.
58 void Reset() noexcept;
59
60 /// Returns true iff already signaled. Never resets the signal.
61 bool IsReady() const noexcept;
62
63 private:
64 std::atomic<std::uintptr_t> state_;
65};
66
67} // namespace engine
68
69USERVER_NAMESPACE_END