userver: userver/engine/single_use_event.hpp Source File
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 <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