userver: userver/engine/impl/future_state.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
future_state.hpp
1#pragma once
2
3#include <atomic>
4#include <exception>
5
6#include <userver/engine/deadline.hpp>
7#include <userver/engine/future_status.hpp>
8#include <userver/engine/impl/context_accessor.hpp>
9#include <userver/engine/impl/wait_list_fwd.hpp>
10#include <userver/utils/result_store.hpp>
11
12USERVER_NAMESPACE_BEGIN
13
14namespace engine::impl {
15
16class FutureStateBase : private ContextAccessor {
17 public:
18 bool IsReady() const noexcept final;
19
20 [[nodiscard]] FutureStatus WaitUntil(Deadline deadline);
21
22 void OnFutureCreated();
23 bool IsFutureCreated() const noexcept;
24
25 // Internal helper for WaitAny/WaitAll
26 ContextAccessor* TryGetContextAccessor() noexcept { return this; }
27
28 protected:
29 FutureStateBase() noexcept;
30 ~FutureStateBase();
31
32 void LockResultStore();
33 void ReleaseResultStore();
34 void WaitForResult();
35
36 private:
37 friend class FutureWaitStrategy<FutureStateBase>;
38
39 EarlyWakeup TryAppendWaiter(TaskContext& waiter) final;
40 void RemoveWaiter(TaskContext& waiter) noexcept final;
41 void AfterWait() noexcept final;
42
43 FastPimplWaitListLight finish_waiters_;
44 std::atomic<bool> is_ready_;
45 std::atomic<bool> is_result_store_locked_;
46 std::atomic<bool> is_future_created_;
47};
48
49template <typename T>
50class FutureState final : public FutureStateBase {
51 public:
52 [[nodiscard]] T Get();
53
54 void SetValue(const T& value);
55 void SetValue(T&& value);
56 void SetException(std::exception_ptr&& ex);
57
58 private:
59 void RethrowErrorResult() const override;
60
61 utils::ResultStore<T> result_store_;
62};
63
64template <>
65class FutureState<void> final : public FutureStateBase {
66 public:
67 void Get();
68
69 void SetValue();
70 void SetException(std::exception_ptr&& ex);
71
72 private:
73 void RethrowErrorResult() const override;
74
75 utils::ResultStore<void> result_store_;
76};
77
78template <typename T>
79T FutureState<T>::Get() {
80 WaitForResult();
81 return result_store_.Retrieve();
82}
83
84template <typename T>
85void FutureState<T>::SetValue(const T& value) {
86 LockResultStore();
87 result_store_.SetValue(value);
88 ReleaseResultStore();
89}
90
91template <typename T>
92void FutureState<T>::SetValue(T&& value) {
93 LockResultStore();
94 result_store_.SetValue(std::move(value));
95 ReleaseResultStore();
96}
97
98template <typename T>
99void FutureState<T>::SetException(std::exception_ptr&& ex) {
100 LockResultStore();
101 result_store_.SetException(std::move(ex));
102 ReleaseResultStore();
103}
104
105template <typename T>
106void FutureState<T>::RethrowErrorResult() const {
107 (void)result_store_.Get();
108}
109
110inline void FutureState<void>::Get() {
111 WaitForResult();
112 return result_store_.Retrieve();
113}
114
115inline void FutureState<void>::SetValue() {
116 LockResultStore();
117 result_store_.SetValue();
118 ReleaseResultStore();
119}
120
121inline void FutureState<void>::SetException(std::exception_ptr&& ex) {
122 LockResultStore();
123 result_store_.SetException(std::move(ex));
124 ReleaseResultStore();
125}
126
127inline void FutureState<void>::RethrowErrorResult() const {
128 (void)result_store_.Get();
129}
130
131} // namespace engine::impl
132
133USERVER_NAMESPACE_END