aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/threading/future
diff options
context:
space:
mode:
authorAnton Samokhvalov <pg83@yandex.ru>2022-02-10 16:45:15 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:15 +0300
commit72cb13b4aff9bc9cf22e49251bc8fd143f82538f (patch)
treeda2c34829458c7d4e74bdfbdf85dff449e9e7fb8 /library/cpp/threading/future
parent778e51ba091dc39e7b7fcab2b9cf4dbedfb6f2b5 (diff)
downloadydb-72cb13b4aff9bc9cf22e49251bc8fd143f82538f.tar.gz
Restoring authorship annotation for Anton Samokhvalov <pg83@yandex.ru>. Commit 1 of 2.
Diffstat (limited to 'library/cpp/threading/future')
-rw-r--r--library/cpp/threading/future/async.h14
-rw-r--r--library/cpp/threading/future/async_ut.cpp48
-rw-r--r--library/cpp/threading/future/core/future-inl.h1200
-rw-r--r--library/cpp/threading/future/core/future.h240
-rw-r--r--library/cpp/threading/future/future_ut.cpp474
-rw-r--r--library/cpp/threading/future/legacy_future.h104
-rw-r--r--library/cpp/threading/future/legacy_future_ut.cpp78
-rw-r--r--library/cpp/threading/future/perf/main.cpp20
-rw-r--r--library/cpp/threading/future/wait/wait-inl.h10
-rw-r--r--library/cpp/threading/future/wait/wait.cpp16
-rw-r--r--library/cpp/threading/future/wait/wait.h8
11 files changed, 1106 insertions, 1106 deletions
diff --git a/library/cpp/threading/future/async.h b/library/cpp/threading/future/async.h
index 8543fdd5c6..f964d2dc88 100644
--- a/library/cpp/threading/future/async.h
+++ b/library/cpp/threading/future/async.h
@@ -2,11 +2,11 @@
#include "future.h"
-#include <util/generic/function.h>
+#include <util/generic/function.h>
#include <util/thread/pool.h>
namespace NThreading {
- /**
+ /**
* @brief Asynchronously executes @arg func in @arg queue returning a future for the result.
*
* @arg func should be a callable object with signature T().
@@ -17,15 +17,15 @@ namespace NThreading {
* If you want to use another queue for execution just write an overload, @see ExtensionExample
* unittest.
*/
- template <typename Func>
+ template <typename Func>
TFuture<TFutureType<TFunctionResult<Func>>> Async(Func&& func, IThreadPool& queue) {
- auto promise = NewPromise<TFutureType<TFunctionResult<Func>>>();
+ auto promise = NewPromise<TFutureType<TFunctionResult<Func>>>();
auto lambda = [promise, func = std::forward<Func>(func)]() mutable {
- NImpl::SetValue(promise, func);
+ NImpl::SetValue(promise, func);
};
queue.SafeAddFunc(std::move(lambda));
- return promise.GetFuture();
- }
+ return promise.GetFuture();
+ }
}
diff --git a/library/cpp/threading/future/async_ut.cpp b/library/cpp/threading/future/async_ut.cpp
index a3699744e4..a452965dbc 100644
--- a/library/cpp/threading/future/async_ut.cpp
+++ b/library/cpp/threading/future/async_ut.cpp
@@ -6,13 +6,13 @@
#include <util/generic/vector.h>
namespace {
- struct TMySuperTaskQueue {
- };
+ struct TMySuperTaskQueue {
+ };
}
namespace NThreading {
- /* Here we provide an Async overload for TMySuperTaskQueue indide NThreading namespace
+ /* Here we provide an Async overload for TMySuperTaskQueue indide NThreading namespace
* so that we can call it in the way
*
* TMySuperTaskQueue queue;
@@ -20,38 +20,38 @@ namespace NThreading {
*
* See also ExtensionExample unittest.
*/
- template <typename Func>
- TFuture<TFunctionResult<Func>> Async(Func func, TMySuperTaskQueue&) {
- return MakeFuture(func());
- }
+ template <typename Func>
+ TFuture<TFunctionResult<Func>> Async(Func func, TMySuperTaskQueue&) {
+ return MakeFuture(func());
+ }
}
Y_UNIT_TEST_SUITE(Async) {
Y_UNIT_TEST(ExtensionExample) {
- TMySuperTaskQueue queue;
- auto future = NThreading::Async([]() { return 5; }, queue);
- future.Wait();
- UNIT_ASSERT_VALUES_EQUAL(future.GetValue(), 5);
- }
+ TMySuperTaskQueue queue;
+ auto future = NThreading::Async([]() { return 5; }, queue);
+ future.Wait();
+ UNIT_ASSERT_VALUES_EQUAL(future.GetValue(), 5);
+ }
Y_UNIT_TEST(WorksWithIMtpQueue) {
auto queue = MakeHolder<TThreadPool>();
- queue->Start(1);
+ queue->Start(1);
- auto future = NThreading::Async([]() { return 5; }, *queue);
- future.Wait();
- UNIT_ASSERT_VALUES_EQUAL(future.GetValue(), 5);
- }
+ auto future = NThreading::Async([]() { return 5; }, *queue);
+ future.Wait();
+ UNIT_ASSERT_VALUES_EQUAL(future.GetValue(), 5);
+ }
Y_UNIT_TEST(ProperlyDeducesFutureType) {
- // Compileability test
+ // Compileability test
auto queue = CreateThreadPool(1);
- NThreading::TFuture<void> f1 = NThreading::Async([]() {}, *queue);
- NThreading::TFuture<int> f2 = NThreading::Async([]() { return 5; }, *queue);
- NThreading::TFuture<double> f3 = NThreading::Async([]() { return 5.0; }, *queue);
- NThreading::TFuture<TVector<int>> f4 = NThreading::Async([]() { return TVector<int>(); }, *queue);
- NThreading::TFuture<int> f5 = NThreading::Async([]() { return NThreading::MakeFuture(5); }, *queue);
- }
+ NThreading::TFuture<void> f1 = NThreading::Async([]() {}, *queue);
+ NThreading::TFuture<int> f2 = NThreading::Async([]() { return 5; }, *queue);
+ NThreading::TFuture<double> f3 = NThreading::Async([]() { return 5.0; }, *queue);
+ NThreading::TFuture<TVector<int>> f4 = NThreading::Async([]() { return TVector<int>(); }, *queue);
+ NThreading::TFuture<int> f5 = NThreading::Async([]() { return NThreading::MakeFuture(5); }, *queue);
+ }
}
diff --git a/library/cpp/threading/future/core/future-inl.h b/library/cpp/threading/future/core/future-inl.h
index 5fd4296a93..a0e06c1891 100644
--- a/library/cpp/threading/future/core/future-inl.h
+++ b/library/cpp/threading/future/core/future-inl.h
@@ -2,92 +2,92 @@
#if !defined(INCLUDE_FUTURE_INL_H)
#error "you should never include future-inl.h directly"
-#endif // INCLUDE_FUTURE_INL_H
+#endif // INCLUDE_FUTURE_INL_H
namespace NThreading {
- namespace NImpl {
- ////////////////////////////////////////////////////////////////////////////////
+ namespace NImpl {
+ ////////////////////////////////////////////////////////////////////////////////
- template <typename T>
- using TCallback = std::function<void(const TFuture<T>&)>;
+ template <typename T>
+ using TCallback = std::function<void(const TFuture<T>&)>;
- template <typename T>
- using TCallbackList = TVector<TCallback<T>>; // TODO: small vector
+ template <typename T>
+ using TCallbackList = TVector<TCallback<T>>; // TODO: small vector
- ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
enum class TError {
Error
};
- template <typename T>
- class TFutureState: public TAtomicRefCount<TFutureState<T>> {
- enum {
- NotReady,
- ExceptionSet,
- ValueMoved, // keep the ordering of this and following values
- ValueSet,
- ValueRead,
- };
-
- private:
- mutable TAtomic State;
- TAdaptiveLock StateLock;
-
- TCallbackList<T> Callbacks;
+ template <typename T>
+ class TFutureState: public TAtomicRefCount<TFutureState<T>> {
+ enum {
+ NotReady,
+ ExceptionSet,
+ ValueMoved, // keep the ordering of this and following values
+ ValueSet,
+ ValueRead,
+ };
+
+ private:
+ mutable TAtomic State;
+ TAdaptiveLock StateLock;
+
+ TCallbackList<T> Callbacks;
mutable THolder<TSystemEvent> ReadyEvent;
- std::exception_ptr Exception;
-
- union {
- char NullValue;
- T Value;
- };
-
- void AccessValue(TDuration timeout, int acquireState) const {
- int state = AtomicGet(State);
- if (Y_UNLIKELY(state == NotReady)) {
- if (timeout == TDuration::Zero()) {
- ythrow TFutureException() << "value not set";
- }
-
- if (!Wait(timeout)) {
- ythrow TFutureException() << "wait timeout";
- }
-
- state = AtomicGet(State);
- }
-
+ std::exception_ptr Exception;
+
+ union {
+ char NullValue;
+ T Value;
+ };
+
+ void AccessValue(TDuration timeout, int acquireState) const {
+ int state = AtomicGet(State);
+ if (Y_UNLIKELY(state == NotReady)) {
+ if (timeout == TDuration::Zero()) {
+ ythrow TFutureException() << "value not set";
+ }
+
+ if (!Wait(timeout)) {
+ ythrow TFutureException() << "wait timeout";
+ }
+
+ state = AtomicGet(State);
+ }
+
TryRethrowWithState(state);
-
- switch (AtomicGetAndCas(&State, acquireState, ValueSet)) {
- case ValueSet:
- break;
- case ValueRead:
- if (acquireState != ValueRead) {
- ythrow TFutureException() << "value being read";
- }
- break;
- case ValueMoved:
- ythrow TFutureException() << "value was moved";
- default:
- Y_ASSERT(state == ValueSet);
- }
- }
-
- public:
- TFutureState()
- : State(NotReady)
- , NullValue(0)
- {
- }
-
- template <typename TT>
- TFutureState(TT&& value)
- : State(ValueSet)
- , Value(std::forward<TT>(value))
- {
- }
+
+ switch (AtomicGetAndCas(&State, acquireState, ValueSet)) {
+ case ValueSet:
+ break;
+ case ValueRead:
+ if (acquireState != ValueRead) {
+ ythrow TFutureException() << "value being read";
+ }
+ break;
+ case ValueMoved:
+ ythrow TFutureException() << "value was moved";
+ default:
+ Y_ASSERT(state == ValueSet);
+ }
+ }
+
+ public:
+ TFutureState()
+ : State(NotReady)
+ , NullValue(0)
+ {
+ }
+
+ template <typename TT>
+ TFutureState(TT&& value)
+ : State(ValueSet)
+ , Value(std::forward<TT>(value))
+ {
+ }
TFutureState(std::exception_ptr exception, TError)
: State(ExceptionSet)
@@ -96,14 +96,14 @@ namespace NThreading {
{
}
- ~TFutureState() {
- if (State >= ValueMoved) { // ValueMoved, ValueSet, ValueRead
- Value.~T();
- }
- }
+ ~TFutureState() {
+ if (State >= ValueMoved) { // ValueMoved, ValueSet, ValueRead
+ Value.~T();
+ }
+ }
- bool HasValue() const {
- return AtomicGet(State) >= ValueMoved; // ValueMoved, ValueSet, ValueRead
+ bool HasValue() const {
+ return AtomicGet(State) >= ValueMoved; // ValueMoved, ValueSet, ValueRead
}
void TryRethrow() const {
@@ -111,22 +111,22 @@ namespace NThreading {
TryRethrowWithState(state);
}
- bool HasException() const {
- return AtomicGet(State) == ExceptionSet;
- }
+ bool HasException() const {
+ return AtomicGet(State) == ExceptionSet;
+ }
- const T& GetValue(TDuration timeout = TDuration::Zero()) const {
- AccessValue(timeout, ValueRead);
- return Value;
- }
+ const T& GetValue(TDuration timeout = TDuration::Zero()) const {
+ AccessValue(timeout, ValueRead);
+ return Value;
+ }
- T ExtractValue(TDuration timeout = TDuration::Zero()) {
- AccessValue(timeout, ValueMoved);
- return std::move(Value);
- }
+ T ExtractValue(TDuration timeout = TDuration::Zero()) {
+ AccessValue(timeout, ValueMoved);
+ return std::move(Value);
+ }
- template <typename TT>
- void SetValue(TT&& value) {
+ template <typename TT>
+ void SetValue(TT&& value) {
bool success = TrySetValue(std::forward<TT>(value));
if (Y_UNLIKELY(!success)) {
ythrow TFutureException() << "value already set";
@@ -136,37 +136,37 @@ namespace NThreading {
template <typename TT>
bool TrySetValue(TT&& value) {
TSystemEvent* readyEvent = nullptr;
- TCallbackList<T> callbacks;
+ TCallbackList<T> callbacks;
- with_lock (StateLock) {
- int state = AtomicGet(State);
- if (Y_UNLIKELY(state != NotReady)) {
+ with_lock (StateLock) {
+ int state = AtomicGet(State);
+ if (Y_UNLIKELY(state != NotReady)) {
return false;
- }
-
- new (&Value) T(std::forward<TT>(value));
+ }
- readyEvent = ReadyEvent.Get();
- callbacks = std::move(Callbacks);
+ new (&Value) T(std::forward<TT>(value));
- AtomicSet(State, ValueSet);
- }
+ readyEvent = ReadyEvent.Get();
+ callbacks = std::move(Callbacks);
- if (readyEvent) {
- readyEvent->Signal();
- }
+ AtomicSet(State, ValueSet);
+ }
- if (callbacks) {
- TFuture<T> temp(this);
- for (auto& callback : callbacks) {
- callback(temp);
- }
- }
+ if (readyEvent) {
+ readyEvent->Signal();
+ }
+
+ if (callbacks) {
+ TFuture<T> temp(this);
+ for (auto& callback : callbacks) {
+ callback(temp);
+ }
+ }
return true;
}
- void SetException(std::exception_ptr e) {
+ void SetException(std::exception_ptr e) {
bool success = TrySetException(std::move(e));
if (Y_UNLIKELY(!success)) {
ythrow TFutureException() << "value already set";
@@ -175,73 +175,73 @@ namespace NThreading {
bool TrySetException(std::exception_ptr e) {
TSystemEvent* readyEvent;
- TCallbackList<T> callbacks;
+ TCallbackList<T> callbacks;
- with_lock (StateLock) {
- int state = AtomicGet(State);
- if (Y_UNLIKELY(state != NotReady)) {
+ with_lock (StateLock) {
+ int state = AtomicGet(State);
+ if (Y_UNLIKELY(state != NotReady)) {
return false;
- }
-
- Exception = std::move(e);
-
- readyEvent = ReadyEvent.Get();
- callbacks = std::move(Callbacks);
-
- AtomicSet(State, ExceptionSet);
- }
-
- if (readyEvent) {
- readyEvent->Signal();
- }
-
- if (callbacks) {
- TFuture<T> temp(this);
- for (auto& callback : callbacks) {
- callback(temp);
- }
- }
+ }
+
+ Exception = std::move(e);
+
+ readyEvent = ReadyEvent.Get();
+ callbacks = std::move(Callbacks);
+
+ AtomicSet(State, ExceptionSet);
+ }
+
+ if (readyEvent) {
+ readyEvent->Signal();
+ }
+
+ if (callbacks) {
+ TFuture<T> temp(this);
+ for (auto& callback : callbacks) {
+ callback(temp);
+ }
+ }
return true;
}
- template <typename F>
- bool Subscribe(F&& func) {
- with_lock (StateLock) {
- int state = AtomicGet(State);
- if (state == NotReady) {
- Callbacks.emplace_back(std::forward<F>(func));
- return true;
- }
- }
- return false;
- }
+ template <typename F>
+ bool Subscribe(F&& func) {
+ with_lock (StateLock) {
+ int state = AtomicGet(State);
+ if (state == NotReady) {
+ Callbacks.emplace_back(std::forward<F>(func));
+ return true;
+ }
+ }
+ return false;
+ }
- void Wait() const {
- Wait(TInstant::Max());
+ void Wait() const {
+ Wait(TInstant::Max());
}
- bool Wait(TDuration timeout) const {
- return Wait(timeout.ToDeadLine());
- }
+ bool Wait(TDuration timeout) const {
+ return Wait(timeout.ToDeadLine());
+ }
- bool Wait(TInstant deadline) const {
+ bool Wait(TInstant deadline) const {
TSystemEvent* readyEvent = nullptr;
- with_lock (StateLock) {
- int state = AtomicGet(State);
- if (state != NotReady) {
- return true;
- }
+ with_lock (StateLock) {
+ int state = AtomicGet(State);
+ if (state != NotReady) {
+ return true;
+ }
- if (!ReadyEvent) {
+ if (!ReadyEvent) {
ReadyEvent.Reset(new TSystemEvent());
- }
- readyEvent = ReadyEvent.Get();
- }
+ }
+ readyEvent = ReadyEvent.Get();
+ }
- Y_ASSERT(readyEvent);
- return readyEvent->WaitD(deadline);
+ Y_ASSERT(readyEvent);
+ return readyEvent->WaitD(deadline);
}
void TryRethrowWithState(int state) const {
@@ -250,31 +250,31 @@ namespace NThreading {
std::rethrow_exception(Exception);
}
}
- };
+ };
- ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
- template <>
- class TFutureState<void>: public TAtomicRefCount<TFutureState<void>> {
- enum {
- NotReady,
- ValueSet,
- ExceptionSet,
- };
+ template <>
+ class TFutureState<void>: public TAtomicRefCount<TFutureState<void>> {
+ enum {
+ NotReady,
+ ValueSet,
+ ExceptionSet,
+ };
- private:
- TAtomic State;
- TAdaptiveLock StateLock;
+ private:
+ TAtomic State;
+ TAdaptiveLock StateLock;
- TCallbackList<void> Callbacks;
+ TCallbackList<void> Callbacks;
mutable THolder<TSystemEvent> ReadyEvent;
- std::exception_ptr Exception;
-
- public:
- TFutureState(bool valueSet = false)
- : State(valueSet ? ValueSet : NotReady)
- {
+ std::exception_ptr Exception;
+
+ public:
+ TFutureState(bool valueSet = false)
+ : State(valueSet ? ValueSet : NotReady)
+ {
}
TFutureState(std::exception_ptr exception, TError)
@@ -283,8 +283,8 @@ namespace NThreading {
{
}
- bool HasValue() const {
- return AtomicGet(State) == ValueSet;
+ bool HasValue() const {
+ return AtomicGet(State) == ValueSet;
}
void TryRethrow() const {
@@ -292,30 +292,30 @@ namespace NThreading {
TryRethrowWithState(state);
}
- bool HasException() const {
- return AtomicGet(State) == ExceptionSet;
- }
+ bool HasException() const {
+ return AtomicGet(State) == ExceptionSet;
+ }
- void GetValue(TDuration timeout = TDuration::Zero()) const {
- int state = AtomicGet(State);
- if (Y_UNLIKELY(state == NotReady)) {
- if (timeout == TDuration::Zero()) {
- ythrow TFutureException() << "value not set";
- }
+ void GetValue(TDuration timeout = TDuration::Zero()) const {
+ int state = AtomicGet(State);
+ if (Y_UNLIKELY(state == NotReady)) {
+ if (timeout == TDuration::Zero()) {
+ ythrow TFutureException() << "value not set";
+ }
- if (!Wait(timeout)) {
- ythrow TFutureException() << "wait timeout";
- }
+ if (!Wait(timeout)) {
+ ythrow TFutureException() << "wait timeout";
+ }
- state = AtomicGet(State);
- }
+ state = AtomicGet(State);
+ }
TryRethrowWithState(state);
- Y_ASSERT(state == ValueSet);
- }
+ Y_ASSERT(state == ValueSet);
+ }
- void SetValue() {
+ void SetValue() {
bool success = TrySetValue();
if (Y_UNLIKELY(!success)) {
ythrow TFutureException() << "value already set";
@@ -324,35 +324,35 @@ namespace NThreading {
bool TrySetValue() {
TSystemEvent* readyEvent = nullptr;
- TCallbackList<void> callbacks;
+ TCallbackList<void> callbacks;
- with_lock (StateLock) {
- int state = AtomicGet(State);
- if (Y_UNLIKELY(state != NotReady)) {
+ with_lock (StateLock) {
+ int state = AtomicGet(State);
+ if (Y_UNLIKELY(state != NotReady)) {
return false;
- }
+ }
- readyEvent = ReadyEvent.Get();
- callbacks = std::move(Callbacks);
+ readyEvent = ReadyEvent.Get();
+ callbacks = std::move(Callbacks);
- AtomicSet(State, ValueSet);
- }
+ AtomicSet(State, ValueSet);
+ }
- if (readyEvent) {
- readyEvent->Signal();
- }
-
- if (callbacks) {
- TFuture<void> temp(this);
- for (auto& callback : callbacks) {
- callback(temp);
- }
- }
+ if (readyEvent) {
+ readyEvent->Signal();
+ }
+
+ if (callbacks) {
+ TFuture<void> temp(this);
+ for (auto& callback : callbacks) {
+ callback(temp);
+ }
+ }
return true;
}
- void SetException(std::exception_ptr e) {
+ void SetException(std::exception_ptr e) {
bool success = TrySetException(std::move(e));
if (Y_UNLIKELY(!success)) {
ythrow TFutureException() << "value already set";
@@ -361,73 +361,73 @@ namespace NThreading {
bool TrySetException(std::exception_ptr e) {
TSystemEvent* readyEvent = nullptr;
- TCallbackList<void> callbacks;
+ TCallbackList<void> callbacks;
- with_lock (StateLock) {
- int state = AtomicGet(State);
- if (Y_UNLIKELY(state != NotReady)) {
+ with_lock (StateLock) {
+ int state = AtomicGet(State);
+ if (Y_UNLIKELY(state != NotReady)) {
return false;
- }
+ }
- Exception = std::move(e);
+ Exception = std::move(e);
- readyEvent = ReadyEvent.Get();
- callbacks = std::move(Callbacks);
+ readyEvent = ReadyEvent.Get();
+ callbacks = std::move(Callbacks);
- AtomicSet(State, ExceptionSet);
- }
+ AtomicSet(State, ExceptionSet);
+ }
- if (readyEvent) {
- readyEvent->Signal();
- }
+ if (readyEvent) {
+ readyEvent->Signal();
+ }
- if (callbacks) {
- TFuture<void> temp(this);
- for (auto& callback : callbacks) {
- callback(temp);
- }
- }
+ if (callbacks) {
+ TFuture<void> temp(this);
+ for (auto& callback : callbacks) {
+ callback(temp);
+ }
+ }
return true;
- }
+ }
- template <typename F>
- bool Subscribe(F&& func) {
- with_lock (StateLock) {
- int state = AtomicGet(State);
- if (state == NotReady) {
- Callbacks.emplace_back(std::forward<F>(func));
- return true;
- }
- }
- return false;
- }
+ template <typename F>
+ bool Subscribe(F&& func) {
+ with_lock (StateLock) {
+ int state = AtomicGet(State);
+ if (state == NotReady) {
+ Callbacks.emplace_back(std::forward<F>(func));
+ return true;
+ }
+ }
+ return false;
+ }
- void Wait() const {
- Wait(TInstant::Max());
+ void Wait() const {
+ Wait(TInstant::Max());
}
- bool Wait(TDuration timeout) const {
- return Wait(timeout.ToDeadLine());
- }
+ bool Wait(TDuration timeout) const {
+ return Wait(timeout.ToDeadLine());
+ }
- bool Wait(TInstant deadline) const {
+ bool Wait(TInstant deadline) const {
TSystemEvent* readyEvent = nullptr;
-
- with_lock (StateLock) {
- int state = AtomicGet(State);
- if (state != NotReady) {
- return true;
- }
-
- if (!ReadyEvent) {
+
+ with_lock (StateLock) {
+ int state = AtomicGet(State);
+ if (state != NotReady) {
+ return true;
+ }
+
+ if (!ReadyEvent) {
ReadyEvent.Reset(new TSystemEvent());
- }
- readyEvent = ReadyEvent.Get();
- }
-
- Y_ASSERT(readyEvent);
- return readyEvent->WaitD(deadline);
+ }
+ readyEvent = ReadyEvent.Get();
+ }
+
+ Y_ASSERT(readyEvent);
+ return readyEvent->WaitD(deadline);
}
void TryRethrowWithState(int state) const {
@@ -436,53 +436,53 @@ namespace NThreading {
std::rethrow_exception(Exception);
}
}
- };
+ };
- ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
- template <typename T>
- inline void SetValueImpl(TPromise<T>& promise, const T& value) {
- promise.SetValue(value);
- }
+ template <typename T>
+ inline void SetValueImpl(TPromise<T>& promise, const T& value) {
+ promise.SetValue(value);
+ }
- template <typename T>
- inline void SetValueImpl(TPromise<T>& promise, T&& value) {
- promise.SetValue(std::move(value));
+ template <typename T>
+ inline void SetValueImpl(TPromise<T>& promise, T&& value) {
+ promise.SetValue(std::move(value));
}
- template <typename T>
+ template <typename T>
inline void SetValueImpl(TPromise<T>& promise, const TFuture<T>& future,
std::enable_if_t<!std::is_void<T>::value, bool> = false) {
- future.Subscribe([=](const TFuture<T>& f) mutable {
+ future.Subscribe([=](const TFuture<T>& f) mutable {
T const* value;
- try {
+ try {
value = &f.GetValue();
- } catch (...) {
- promise.SetException(std::current_exception());
+ } catch (...) {
+ promise.SetException(std::current_exception());
return;
- }
+ }
promise.SetValue(*value);
- });
+ });
}
template <typename T>
inline void SetValueImpl(TPromise<void>& promise, const TFuture<T>& future) {
future.Subscribe([=](const TFuture<T>& f) mutable {
- try {
+ try {
f.TryRethrow();
- } catch (...) {
- promise.SetException(std::current_exception());
+ } catch (...) {
+ promise.SetException(std::current_exception());
return;
- }
+ }
promise.SetValue();
- });
- }
-
- template <typename T, typename F>
- inline void SetValue(TPromise<T>& promise, F&& func) {
- try {
- SetValueImpl(promise, func());
- } catch (...) {
+ });
+ }
+
+ template <typename T, typename F>
+ inline void SetValue(TPromise<T>& promise, F&& func) {
+ try {
+ SetValueImpl(promise, func());
+ } catch (...) {
const bool success = promise.TrySetException(std::current_exception());
if (Y_UNLIKELY(!success)) {
throw;
@@ -490,21 +490,21 @@ namespace NThreading {
}
}
- template <typename F>
- inline void SetValue(TPromise<void>& promise, F&& func,
- std::enable_if_t<std::is_void<TFunctionResult<F>>::value, bool> = false) {
- try {
- func();
- } catch (...) {
- promise.SetException(std::current_exception());
+ template <typename F>
+ inline void SetValue(TPromise<void>& promise, F&& func,
+ std::enable_if_t<std::is_void<TFunctionResult<F>>::value, bool> = false) {
+ try {
+ func();
+ } catch (...) {
+ promise.SetException(std::current_exception());
return;
}
promise.SetValue();
}
- }
+ }
- ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
class TFutureStateId {
private:
@@ -532,45 +532,45 @@ namespace NThreading {
////////////////////////////////////////////////////////////////////////////////
- template <typename T>
+ template <typename T>
inline TFuture<T>::TFuture(const TIntrusivePtr<TFutureState>& state) noexcept
- : State(state)
+ : State(state)
{
}
- template <typename T>
- inline void TFuture<T>::Swap(TFuture<T>& other) {
- State.Swap(other.State);
- }
+ template <typename T>
+ inline void TFuture<T>::Swap(TFuture<T>& other) {
+ State.Swap(other.State);
+ }
- template <typename T>
- inline bool TFuture<T>::HasValue() const {
- return State && State->HasValue();
- }
+ template <typename T>
+ inline bool TFuture<T>::HasValue() const {
+ return State && State->HasValue();
+ }
- template <typename T>
- inline const T& TFuture<T>::GetValue(TDuration timeout) const {
- EnsureInitialized();
- return State->GetValue(timeout);
+ template <typename T>
+ inline const T& TFuture<T>::GetValue(TDuration timeout) const {
+ EnsureInitialized();
+ return State->GetValue(timeout);
}
- template <typename T>
- inline T TFuture<T>::ExtractValue(TDuration timeout) {
- EnsureInitialized();
- return State->ExtractValue(timeout);
- }
+ template <typename T>
+ inline T TFuture<T>::ExtractValue(TDuration timeout) {
+ EnsureInitialized();
+ return State->ExtractValue(timeout);
+ }
- template <typename T>
- inline const T& TFuture<T>::GetValueSync() const {
- return GetValue(TDuration::Max());
- }
+ template <typename T>
+ inline const T& TFuture<T>::GetValueSync() const {
+ return GetValue(TDuration::Max());
+ }
- template <typename T>
- inline T TFuture<T>::ExtractValueSync() {
- return ExtractValue(TDuration::Max());
- }
+ template <typename T>
+ inline T TFuture<T>::ExtractValueSync() {
+ return ExtractValue(TDuration::Max());
+ }
- template <typename T>
+ template <typename T>
inline void TFuture<T>::TryRethrow() const {
if (State) {
State->TryRethrow();
@@ -578,40 +578,40 @@ namespace NThreading {
}
template <typename T>
- inline bool TFuture<T>::HasException() const {
- return State && State->HasException();
- }
-
- template <typename T>
- inline void TFuture<T>::Wait() const {
- EnsureInitialized();
- return State->Wait();
- }
-
- template <typename T>
- inline bool TFuture<T>::Wait(TDuration timeout) const {
- EnsureInitialized();
- return State->Wait(timeout);
- }
-
- template <typename T>
- inline bool TFuture<T>::Wait(TInstant deadline) const {
- EnsureInitialized();
- return State->Wait(deadline);
- }
-
- template <typename T>
- template <typename F>
- inline const TFuture<T>& TFuture<T>::Subscribe(F&& func) const {
- EnsureInitialized();
- if (!State->Subscribe(std::forward<F>(func))) {
- func(*this);
- }
- return *this;
- }
-
- template <typename T>
- template <typename F>
+ inline bool TFuture<T>::HasException() const {
+ return State && State->HasException();
+ }
+
+ template <typename T>
+ inline void TFuture<T>::Wait() const {
+ EnsureInitialized();
+ return State->Wait();
+ }
+
+ template <typename T>
+ inline bool TFuture<T>::Wait(TDuration timeout) const {
+ EnsureInitialized();
+ return State->Wait(timeout);
+ }
+
+ template <typename T>
+ inline bool TFuture<T>::Wait(TInstant deadline) const {
+ EnsureInitialized();
+ return State->Wait(deadline);
+ }
+
+ template <typename T>
+ template <typename F>
+ inline const TFuture<T>& TFuture<T>::Subscribe(F&& func) const {
+ EnsureInitialized();
+ if (!State->Subscribe(std::forward<F>(func))) {
+ func(*this);
+ }
+ return *this;
+ }
+
+ template <typename T>
+ template <typename F>
inline const TFuture<T>& TFuture<T>::NoexceptSubscribe(F&& func) const noexcept {
return Subscribe(std::forward<F>(func));
}
@@ -623,59 +623,59 @@ namespace NThreading {
auto promise = NewPromise<TFutureType<TFutureCallResult<F, T>>>();
Subscribe([promise, func = std::forward<F>(func)](const TFuture<T>& future) mutable {
NImpl::SetValue(promise, [&]() { return func(future); });
- });
- return promise;
- }
-
- template <typename T>
- inline TFuture<void> TFuture<T>::IgnoreResult() const {
- auto promise = NewPromise();
- Subscribe([=](const TFuture<T>& future) mutable {
+ });
+ return promise;
+ }
+
+ template <typename T>
+ inline TFuture<void> TFuture<T>::IgnoreResult() const {
+ auto promise = NewPromise();
+ Subscribe([=](const TFuture<T>& future) mutable {
NImpl::SetValueImpl(promise, future);
- });
- return promise;
- }
+ });
+ return promise;
+ }
- template <typename T>
- inline bool TFuture<T>::Initialized() const {
- return bool(State);
+ template <typename T>
+ inline bool TFuture<T>::Initialized() const {
+ return bool(State);
}
- template <typename T>
+ template <typename T>
inline TMaybe<TFutureStateId> TFuture<T>::StateId() const noexcept {
return State != nullptr ? MakeMaybe<TFutureStateId>(*State) : Nothing();
}
template <typename T>
- inline void TFuture<T>::EnsureInitialized() const {
- if (!State) {
- ythrow TFutureException() << "state not initialized";
+ inline void TFuture<T>::EnsureInitialized() const {
+ if (!State) {
+ ythrow TFutureException() << "state not initialized";
}
- }
+ }
- ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
inline TFuture<void>::TFuture(const TIntrusivePtr<TFutureState>& state) noexcept
- : State(state)
- {
- }
+ : State(state)
+ {
+ }
- inline void TFuture<void>::Swap(TFuture<void>& other) {
- State.Swap(other.State);
- }
+ inline void TFuture<void>::Swap(TFuture<void>& other) {
+ State.Swap(other.State);
+ }
- inline bool TFuture<void>::HasValue() const {
- return State && State->HasValue();
- }
+ inline bool TFuture<void>::HasValue() const {
+ return State && State->HasValue();
+ }
- inline void TFuture<void>::GetValue(TDuration timeout) const {
- EnsureInitialized();
- State->GetValue(timeout);
- }
+ inline void TFuture<void>::GetValue(TDuration timeout) const {
+ EnsureInitialized();
+ State->GetValue(timeout);
+ }
- inline void TFuture<void>::GetValueSync() const {
- GetValue(TDuration::Max());
- }
+ inline void TFuture<void>::GetValueSync() const {
+ GetValue(TDuration::Max());
+ }
inline void TFuture<void>::TryRethrow() const {
if (State) {
@@ -683,35 +683,35 @@ namespace NThreading {
}
}
- inline bool TFuture<void>::HasException() const {
- return State && State->HasException();
- }
+ inline bool TFuture<void>::HasException() const {
+ return State && State->HasException();
+ }
- inline void TFuture<void>::Wait() const {
- EnsureInitialized();
- return State->Wait();
- }
+ inline void TFuture<void>::Wait() const {
+ EnsureInitialized();
+ return State->Wait();
+ }
- inline bool TFuture<void>::Wait(TDuration timeout) const {
- EnsureInitialized();
- return State->Wait(timeout);
- }
+ inline bool TFuture<void>::Wait(TDuration timeout) const {
+ EnsureInitialized();
+ return State->Wait(timeout);
+ }
- inline bool TFuture<void>::Wait(TInstant deadline) const {
- EnsureInitialized();
- return State->Wait(deadline);
- }
+ inline bool TFuture<void>::Wait(TInstant deadline) const {
+ EnsureInitialized();
+ return State->Wait(deadline);
+ }
- template <typename F>
- inline const TFuture<void>& TFuture<void>::Subscribe(F&& func) const {
- EnsureInitialized();
- if (!State->Subscribe(std::forward<F>(func))) {
- func(*this);
- }
- return *this;
- }
+ template <typename F>
+ inline const TFuture<void>& TFuture<void>::Subscribe(F&& func) const {
+ EnsureInitialized();
+ if (!State->Subscribe(std::forward<F>(func))) {
+ func(*this);
+ }
+ return *this;
+ }
- template <typename F>
+ template <typename F>
inline const TFuture<void>& TFuture<void>::NoexceptSubscribe(F&& func) const noexcept {
return Subscribe(std::forward<F>(func));
}
@@ -722,82 +722,82 @@ namespace NThreading {
auto promise = NewPromise<TFutureType<TFutureCallResult<F, void>>>();
Subscribe([promise, func = std::forward<F>(func)](const TFuture<void>& future) mutable {
NImpl::SetValue(promise, [&]() { return func(future); });
- });
- return promise;
- }
-
- template <typename R>
- inline TFuture<R> TFuture<void>::Return(const R& value) const {
- auto promise = NewPromise<R>();
- Subscribe([=](const TFuture<void>& future) mutable {
- try {
+ });
+ return promise;
+ }
+
+ template <typename R>
+ inline TFuture<R> TFuture<void>::Return(const R& value) const {
+ auto promise = NewPromise<R>();
+ Subscribe([=](const TFuture<void>& future) mutable {
+ try {
future.TryRethrow();
- } catch (...) {
- promise.SetException(std::current_exception());
+ } catch (...) {
+ promise.SetException(std::current_exception());
return;
- }
+ }
promise.SetValue(value);
- });
- return promise;
+ });
+ return promise;
}
- inline bool TFuture<void>::Initialized() const {
- return bool(State);
- }
+ inline bool TFuture<void>::Initialized() const {
+ return bool(State);
+ }
inline TMaybe<TFutureStateId> TFuture<void>::StateId() const noexcept {
return State != nullptr ? MakeMaybe<TFutureStateId>(*State) : Nothing();
}
- inline void TFuture<void>::EnsureInitialized() const {
- if (!State) {
- ythrow TFutureException() << "state not initialized";
+ inline void TFuture<void>::EnsureInitialized() const {
+ if (!State) {
+ ythrow TFutureException() << "state not initialized";
}
- }
+ }
- ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
- template <typename T>
+ template <typename T>
inline TPromise<T>::TPromise(const TIntrusivePtr<TFutureState>& state) noexcept
- : State(state)
- {
- }
-
- template <typename T>
- inline void TPromise<T>::Swap(TPromise<T>& other) {
- State.Swap(other.State);
- }
-
- template <typename T>
- inline const T& TPromise<T>::GetValue() const {
- EnsureInitialized();
- return State->GetValue();
- }
-
- template <typename T>
- inline T TPromise<T>::ExtractValue() {
- EnsureInitialized();
- return State->ExtractValue();
- }
-
- template <typename T>
- inline bool TPromise<T>::HasValue() const {
- return State && State->HasValue();
- }
-
- template <typename T>
- inline void TPromise<T>::SetValue(const T& value) {
- EnsureInitialized();
- State->SetValue(value);
- }
-
- template <typename T>
- inline void TPromise<T>::SetValue(T&& value) {
- EnsureInitialized();
- State->SetValue(std::move(value));
- }
-
- template <typename T>
+ : State(state)
+ {
+ }
+
+ template <typename T>
+ inline void TPromise<T>::Swap(TPromise<T>& other) {
+ State.Swap(other.State);
+ }
+
+ template <typename T>
+ inline const T& TPromise<T>::GetValue() const {
+ EnsureInitialized();
+ return State->GetValue();
+ }
+
+ template <typename T>
+ inline T TPromise<T>::ExtractValue() {
+ EnsureInitialized();
+ return State->ExtractValue();
+ }
+
+ template <typename T>
+ inline bool TPromise<T>::HasValue() const {
+ return State && State->HasValue();
+ }
+
+ template <typename T>
+ inline void TPromise<T>::SetValue(const T& value) {
+ EnsureInitialized();
+ State->SetValue(value);
+ }
+
+ template <typename T>
+ inline void TPromise<T>::SetValue(T&& value) {
+ EnsureInitialized();
+ State->SetValue(std::move(value));
+ }
+
+ template <typename T>
inline bool TPromise<T>::TrySetValue(const T& value) {
EnsureInitialized();
return State->TrySetValue(value);
@@ -817,75 +817,75 @@ namespace NThreading {
}
template <typename T>
- inline bool TPromise<T>::HasException() const {
- return State && State->HasException();
- }
+ inline bool TPromise<T>::HasException() const {
+ return State && State->HasException();
+ }
- template <typename T>
- inline void TPromise<T>::SetException(const TString& e) {
- EnsureInitialized();
- State->SetException(std::make_exception_ptr(yexception() << e));
- }
+ template <typename T>
+ inline void TPromise<T>::SetException(const TString& e) {
+ EnsureInitialized();
+ State->SetException(std::make_exception_ptr(yexception() << e));
+ }
- template <typename T>
- inline void TPromise<T>::SetException(std::exception_ptr e) {
- EnsureInitialized();
- State->SetException(std::move(e));
- }
+ template <typename T>
+ inline void TPromise<T>::SetException(std::exception_ptr e) {
+ EnsureInitialized();
+ State->SetException(std::move(e));
+ }
- template <typename T>
+ template <typename T>
inline bool TPromise<T>::TrySetException(std::exception_ptr e) {
EnsureInitialized();
return State->TrySetException(std::move(e));
}
template <typename T>
- inline TFuture<T> TPromise<T>::GetFuture() const {
- EnsureInitialized();
- return TFuture<T>(State);
- }
+ inline TFuture<T> TPromise<T>::GetFuture() const {
+ EnsureInitialized();
+ return TFuture<T>(State);
+ }
- template <typename T>
- inline TPromise<T>::operator TFuture<T>() const {
- return GetFuture();
- }
+ template <typename T>
+ inline TPromise<T>::operator TFuture<T>() const {
+ return GetFuture();
+ }
- template <typename T>
- inline bool TPromise<T>::Initialized() const {
- return bool(State);
- }
+ template <typename T>
+ inline bool TPromise<T>::Initialized() const {
+ return bool(State);
+ }
- template <typename T>
- inline void TPromise<T>::EnsureInitialized() const {
- if (!State) {
- ythrow TFutureException() << "state not initialized";
- }
- }
+ template <typename T>
+ inline void TPromise<T>::EnsureInitialized() const {
+ if (!State) {
+ ythrow TFutureException() << "state not initialized";
+ }
+ }
- ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
inline TPromise<void>::TPromise(const TIntrusivePtr<TFutureState>& state) noexcept
- : State(state)
- {
- }
+ : State(state)
+ {
+ }
- inline void TPromise<void>::Swap(TPromise<void>& other) {
- State.Swap(other.State);
- }
+ inline void TPromise<void>::Swap(TPromise<void>& other) {
+ State.Swap(other.State);
+ }
- inline void TPromise<void>::GetValue() const {
- EnsureInitialized();
- State->GetValue();
- }
+ inline void TPromise<void>::GetValue() const {
+ EnsureInitialized();
+ State->GetValue();
+ }
- inline bool TPromise<void>::HasValue() const {
- return State && State->HasValue();
- }
+ inline bool TPromise<void>::HasValue() const {
+ return State && State->HasValue();
+ }
- inline void TPromise<void>::SetValue() {
- EnsureInitialized();
- State->SetValue();
- }
+ inline void TPromise<void>::SetValue() {
+ EnsureInitialized();
+ State->SetValue();
+ }
inline bool TPromise<void>::TrySetValue() {
EnsureInitialized();
@@ -898,78 +898,78 @@ namespace NThreading {
}
}
- inline bool TPromise<void>::HasException() const {
- return State && State->HasException();
- }
+ inline bool TPromise<void>::HasException() const {
+ return State && State->HasException();
+ }
- inline void TPromise<void>::SetException(const TString& e) {
- EnsureInitialized();
- State->SetException(std::make_exception_ptr(yexception() << e));
- }
+ inline void TPromise<void>::SetException(const TString& e) {
+ EnsureInitialized();
+ State->SetException(std::make_exception_ptr(yexception() << e));
+ }
- inline void TPromise<void>::SetException(std::exception_ptr e) {
- EnsureInitialized();
- State->SetException(std::move(e));
- }
+ inline void TPromise<void>::SetException(std::exception_ptr e) {
+ EnsureInitialized();
+ State->SetException(std::move(e));
+ }
inline bool TPromise<void>::TrySetException(std::exception_ptr e) {
EnsureInitialized();
return State->TrySetException(std::move(e));
}
- inline TFuture<void> TPromise<void>::GetFuture() const {
- EnsureInitialized();
- return TFuture<void>(State);
- }
+ inline TFuture<void> TPromise<void>::GetFuture() const {
+ EnsureInitialized();
+ return TFuture<void>(State);
+ }
- inline TPromise<void>::operator TFuture<void>() const {
- return GetFuture();
- }
+ inline TPromise<void>::operator TFuture<void>() const {
+ return GetFuture();
+ }
- inline bool TPromise<void>::Initialized() const {
- return bool(State);
- }
+ inline bool TPromise<void>::Initialized() const {
+ return bool(State);
+ }
- inline void TPromise<void>::EnsureInitialized() const {
- if (!State) {
- ythrow TFutureException() << "state not initialized";
- }
- }
+ inline void TPromise<void>::EnsureInitialized() const {
+ if (!State) {
+ ythrow TFutureException() << "state not initialized";
+ }
+ }
- ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
- template <typename T>
- inline TPromise<T> NewPromise() {
- return {new NImpl::TFutureState<T>()};
+ template <typename T>
+ inline TPromise<T> NewPromise() {
+ return {new NImpl::TFutureState<T>()};
}
- inline TPromise<void> NewPromise() {
- return {new NImpl::TFutureState<void>()};
- }
+ inline TPromise<void> NewPromise() {
+ return {new NImpl::TFutureState<void>()};
+ }
- template <typename T>
- inline TFuture<T> MakeFuture(const T& value) {
- return {new NImpl::TFutureState<T>(value)};
- }
+ template <typename T>
+ inline TFuture<T> MakeFuture(const T& value) {
+ return {new NImpl::TFutureState<T>(value)};
+ }
- template <typename T>
- inline TFuture<std::remove_reference_t<T>> MakeFuture(T&& value) {
- return {new NImpl::TFutureState<std::remove_reference_t<T>>(std::forward<T>(value))};
- }
+ template <typename T>
+ inline TFuture<std::remove_reference_t<T>> MakeFuture(T&& value) {
+ return {new NImpl::TFutureState<std::remove_reference_t<T>>(std::forward<T>(value))};
+ }
- template <typename T>
- inline TFuture<T> MakeFuture() {
- struct TCache {
- TFuture<T> Instance{new NImpl::TFutureState<T>(Default<T>())};
+ template <typename T>
+ inline TFuture<T> MakeFuture() {
+ struct TCache {
+ TFuture<T> Instance{new NImpl::TFutureState<T>(Default<T>())};
TCache() {
// Immediately advance state from ValueSet to ValueRead.
// This should prevent corrupting shared value with an ExtractValue() call.
Y_UNUSED(Instance.GetValue());
}
- };
- return Singleton<TCache>()->Instance;
- }
+ };
+ return Singleton<TCache>()->Instance;
+ }
template <typename T>
inline TFuture<T> MakeErrorFuture(std::exception_ptr exception)
@@ -977,10 +977,10 @@ namespace NThreading {
return {new NImpl::TFutureState<T>(std::move(exception), NImpl::TError::Error)};
}
- inline TFuture<void> MakeFuture() {
- struct TCache {
- TFuture<void> Instance{new NImpl::TFutureState<void>(true)};
- };
- return Singleton<TCache>()->Instance;
- }
+ inline TFuture<void> MakeFuture() {
+ struct TCache {
+ TFuture<void> Instance{new NImpl::TFutureState<void>(true)};
+ };
+ return Singleton<TCache>()->Instance;
+ }
}
diff --git a/library/cpp/threading/future/core/future.h b/library/cpp/threading/future/core/future.h
index 2e82bb953e..12623389ca 100644
--- a/library/cpp/threading/future/core/future.h
+++ b/library/cpp/threading/future/core/future.h
@@ -12,51 +12,51 @@
#include <util/system/spinlock.h>
namespace NThreading {
- ////////////////////////////////////////////////////////////////////////////////
-
- struct TFutureException: public yexception {};
-
- // creates unset promise
- template <typename T>
- TPromise<T> NewPromise();
- TPromise<void> NewPromise();
-
- // creates preset future
- template <typename T>
- TFuture<T> MakeFuture(const T& value);
- template <typename T>
- TFuture<std::remove_reference_t<T>> MakeFuture(T&& value);
- template <typename T>
- TFuture<T> MakeFuture();
+ ////////////////////////////////////////////////////////////////////////////////
+
+ struct TFutureException: public yexception {};
+
+ // creates unset promise
+ template <typename T>
+ TPromise<T> NewPromise();
+ TPromise<void> NewPromise();
+
+ // creates preset future
+ template <typename T>
+ TFuture<T> MakeFuture(const T& value);
+ template <typename T>
+ TFuture<std::remove_reference_t<T>> MakeFuture(T&& value);
+ template <typename T>
+ TFuture<T> MakeFuture();
template <typename T>
TFuture<T> MakeErrorFuture(std::exception_ptr exception);
- TFuture<void> MakeFuture();
+ TFuture<void> MakeFuture();
- ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
- namespace NImpl {
- template <typename T>
- class TFutureState;
+ namespace NImpl {
+ template <typename T>
+ class TFutureState;
- template <typename T>
- struct TFutureType {
- using TType = T;
- };
+ template <typename T>
+ struct TFutureType {
+ using TType = T;
+ };
- template <typename T>
- struct TFutureType<TFuture<T>> {
- using TType = typename TFutureType<T>::TType;
- };
+ template <typename T>
+ struct TFutureType<TFuture<T>> {
+ using TType = typename TFutureType<T>::TType;
+ };
template <typename F, typename T>
struct TFutureCallResult {
// NOTE: separate class for msvc compatibility
using TType = decltype(std::declval<F&>()(std::declval<const TFuture<T>&>()));
};
- }
+ }
- template <typename F>
- using TFutureType = typename NImpl::TFutureType<F>::TType;
+ template <typename F>
+ using TFutureType = typename NImpl::TFutureType<F>::TType;
template <typename F, typename T>
using TFutureCallResult = typename NImpl::TFutureCallResult<F, T>::TType;
@@ -64,16 +64,16 @@ namespace NThreading {
//! Type of the future/promise state identifier
class TFutureStateId;
- ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
- template <typename T>
- class TFuture {
- using TFutureState = NImpl::TFutureState<T>;
+ template <typename T>
+ class TFuture {
+ using TFutureState = NImpl::TFutureState<T>;
- private:
- TIntrusivePtr<TFutureState> State;
+ private:
+ TIntrusivePtr<TFutureState> State;
- public:
+ public:
using value_type = T;
TFuture() noexcept = default;
@@ -83,54 +83,54 @@ namespace NThreading {
TFuture<T>& operator=(const TFuture<T>& other) noexcept = default;
TFuture<T>& operator=(TFuture<T>&& other) noexcept = default;
- void Swap(TFuture<T>& other);
+ void Swap(TFuture<T>& other);
- bool Initialized() const;
+ bool Initialized() const;
- bool HasValue() const;
- const T& GetValue(TDuration timeout = TDuration::Zero()) const;
- const T& GetValueSync() const;
- T ExtractValue(TDuration timeout = TDuration::Zero());
- T ExtractValueSync();
+ bool HasValue() const;
+ const T& GetValue(TDuration timeout = TDuration::Zero()) const;
+ const T& GetValueSync() const;
+ T ExtractValue(TDuration timeout = TDuration::Zero());
+ T ExtractValueSync();
void TryRethrow() const;
- bool HasException() const;
+ bool HasException() const;
- void Wait() const;
- bool Wait(TDuration timeout) const;
- bool Wait(TInstant deadline) const;
+ void Wait() const;
+ bool Wait(TDuration timeout) const;
+ bool Wait(TInstant deadline) const;
- template <typename F>
- const TFuture<T>& Subscribe(F&& callback) const;
+ template <typename F>
+ const TFuture<T>& Subscribe(F&& callback) const;
// precondition: EnsureInitialized() passes
// postcondition: std::terminate is highly unlikely
- template <typename F>
+ template <typename F>
const TFuture<T>& NoexceptSubscribe(F&& callback) const noexcept;
template <typename F>
TFuture<TFutureType<TFutureCallResult<F, T>>> Apply(F&& func) const;
- TFuture<void> IgnoreResult() const;
+ TFuture<void> IgnoreResult() const;
//! If the future is initialized returns the future state identifier. Otherwise returns an empty optional
/** The state identifier is guaranteed to be unique during the future state lifetime and could be reused after its death
**/
TMaybe<TFutureStateId> StateId() const noexcept;
- void EnsureInitialized() const;
- };
+ void EnsureInitialized() const;
+ };
- ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
- template <>
- class TFuture<void> {
- using TFutureState = NImpl::TFutureState<void>;
+ template <>
+ class TFuture<void> {
+ using TFutureState = NImpl::TFutureState<void>;
- private:
+ private:
TIntrusivePtr<TFutureState> State = nullptr;
- public:
+ public:
using value_type = void;
TFuture() noexcept = default;
@@ -140,34 +140,34 @@ namespace NThreading {
TFuture<void>& operator=(const TFuture<void>& other) noexcept = default;
TFuture<void>& operator=(TFuture<void>&& other) noexcept = default;
- void Swap(TFuture<void>& other);
+ void Swap(TFuture<void>& other);
- bool Initialized() const;
+ bool Initialized() const;
- bool HasValue() const;
- void GetValue(TDuration timeout = TDuration::Zero()) const;
- void GetValueSync() const;
+ bool HasValue() const;
+ void GetValue(TDuration timeout = TDuration::Zero()) const;
+ void GetValueSync() const;
void TryRethrow() const;
- bool HasException() const;
+ bool HasException() const;
- void Wait() const;
- bool Wait(TDuration timeout) const;
- bool Wait(TInstant deadline) const;
+ void Wait() const;
+ bool Wait(TDuration timeout) const;
+ bool Wait(TInstant deadline) const;
- template <typename F>
- const TFuture<void>& Subscribe(F&& callback) const;
+ template <typename F>
+ const TFuture<void>& Subscribe(F&& callback) const;
// precondition: EnsureInitialized() passes
// postcondition: std::terminate is highly unlikely
- template <typename F>
+ template <typename F>
const TFuture<void>& NoexceptSubscribe(F&& callback) const noexcept;
template <typename F>
TFuture<TFutureType<TFutureCallResult<F, void>>> Apply(F&& func) const;
- template <typename R>
- TFuture<R> Return(const R& value) const;
+ template <typename R>
+ TFuture<R> Return(const R& value) const;
TFuture<void> IgnoreResult() const {
return *this;
@@ -178,19 +178,19 @@ namespace NThreading {
**/
TMaybe<TFutureStateId> StateId() const noexcept;
- void EnsureInitialized() const;
- };
+ void EnsureInitialized() const;
+ };
- ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
- template <typename T>
- class TPromise {
- using TFutureState = NImpl::TFutureState<T>;
+ template <typename T>
+ class TPromise {
+ using TFutureState = NImpl::TFutureState<T>;
- private:
+ private:
TIntrusivePtr<TFutureState> State = nullptr;
- public:
+ public:
TPromise() noexcept = default;
TPromise(const TPromise<T>& other) noexcept = default;
TPromise(TPromise<T>&& other) noexcept = default;
@@ -198,43 +198,43 @@ namespace NThreading {
TPromise<T>& operator=(const TPromise<T>& other) noexcept = default;
TPromise<T>& operator=(TPromise<T>&& other) noexcept = default;
- void Swap(TPromise<T>& other);
+ void Swap(TPromise<T>& other);
- bool Initialized() const;
+ bool Initialized() const;
- bool HasValue() const;
- const T& GetValue() const;
- T ExtractValue();
+ bool HasValue() const;
+ const T& GetValue() const;
+ T ExtractValue();
- void SetValue(const T& value);
- void SetValue(T&& value);
+ void SetValue(const T& value);
+ void SetValue(T&& value);
bool TrySetValue(const T& value);
bool TrySetValue(T&& value);
void TryRethrow() const;
- bool HasException() const;
- void SetException(const TString& e);
- void SetException(std::exception_ptr e);
+ bool HasException() const;
+ void SetException(const TString& e);
+ void SetException(std::exception_ptr e);
bool TrySetException(std::exception_ptr e);
- TFuture<T> GetFuture() const;
- operator TFuture<T>() const;
+ TFuture<T> GetFuture() const;
+ operator TFuture<T>() const;
- private:
- void EnsureInitialized() const;
- };
+ private:
+ void EnsureInitialized() const;
+ };
- ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
- template <>
- class TPromise<void> {
- using TFutureState = NImpl::TFutureState<void>;
+ template <>
+ class TPromise<void> {
+ using TFutureState = NImpl::TFutureState<void>;
- private:
- TIntrusivePtr<TFutureState> State;
+ private:
+ TIntrusivePtr<TFutureState> State;
- public:
+ public:
TPromise() noexcept = default;
TPromise(const TPromise<void>& other) noexcept = default;
TPromise(TPromise<void>&& other) noexcept = default;
@@ -242,30 +242,30 @@ namespace NThreading {
TPromise<void>& operator=(const TPromise<void>& other) noexcept = default;
TPromise<void>& operator=(TPromise<void>&& other) noexcept = default;
- void Swap(TPromise<void>& other);
+ void Swap(TPromise<void>& other);
- bool Initialized() const;
+ bool Initialized() const;
- bool HasValue() const;
- void GetValue() const;
+ bool HasValue() const;
+ void GetValue() const;
- void SetValue();
+ void SetValue();
bool TrySetValue();
void TryRethrow() const;
- bool HasException() const;
- void SetException(const TString& e);
- void SetException(std::exception_ptr e);
+ bool HasException() const;
+ void SetException(const TString& e);
+ void SetException(std::exception_ptr e);
bool TrySetException(std::exception_ptr e);
- TFuture<void> GetFuture() const;
- operator TFuture<void>() const;
+ TFuture<void> GetFuture() const;
+ operator TFuture<void>() const;
- private:
- void EnsureInitialized() const;
- };
+ private:
+ void EnsureInitialized() const;
+ };
-}
+}
#define INCLUDE_FUTURE_INL_H
#include "future-inl.h"
diff --git a/library/cpp/threading/future/future_ut.cpp b/library/cpp/threading/future/future_ut.cpp
index 05950a568d..636b113f2f 100644
--- a/library/cpp/threading/future/future_ut.cpp
+++ b/library/cpp/threading/future/future_ut.cpp
@@ -62,180 +62,180 @@ namespace {
}
- ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
Y_UNIT_TEST_SUITE(TFutureTest) {
Y_UNIT_TEST(ShouldInitiallyHasNoValue) {
- TPromise<int> promise;
- UNIT_ASSERT(!promise.HasValue());
+ TPromise<int> promise;
+ UNIT_ASSERT(!promise.HasValue());
- promise = NewPromise<int>();
- UNIT_ASSERT(!promise.HasValue());
+ promise = NewPromise<int>();
+ UNIT_ASSERT(!promise.HasValue());
- TFuture<int> future;
- UNIT_ASSERT(!future.HasValue());
+ TFuture<int> future;
+ UNIT_ASSERT(!future.HasValue());
- future = promise.GetFuture();
- UNIT_ASSERT(!future.HasValue());
- }
+ future = promise.GetFuture();
+ UNIT_ASSERT(!future.HasValue());
+ }
Y_UNIT_TEST(ShouldInitiallyHasNoValueVoid) {
- TPromise<void> promise;
- UNIT_ASSERT(!promise.HasValue());
+ TPromise<void> promise;
+ UNIT_ASSERT(!promise.HasValue());
- promise = NewPromise();
- UNIT_ASSERT(!promise.HasValue());
+ promise = NewPromise();
+ UNIT_ASSERT(!promise.HasValue());
- TFuture<void> future;
- UNIT_ASSERT(!future.HasValue());
+ TFuture<void> future;
+ UNIT_ASSERT(!future.HasValue());
- future = promise.GetFuture();
- UNIT_ASSERT(!future.HasValue());
- }
+ future = promise.GetFuture();
+ UNIT_ASSERT(!future.HasValue());
+ }
Y_UNIT_TEST(ShouldStoreValue) {
- TPromise<int> promise = NewPromise<int>();
- promise.SetValue(123);
- UNIT_ASSERT(promise.HasValue());
- UNIT_ASSERT_EQUAL(promise.GetValue(), 123);
+ TPromise<int> promise = NewPromise<int>();
+ promise.SetValue(123);
+ UNIT_ASSERT(promise.HasValue());
+ UNIT_ASSERT_EQUAL(promise.GetValue(), 123);
- TFuture<int> future = promise.GetFuture();
- UNIT_ASSERT(future.HasValue());
- UNIT_ASSERT_EQUAL(future.GetValue(), 123);
+ TFuture<int> future = promise.GetFuture();
+ UNIT_ASSERT(future.HasValue());
+ UNIT_ASSERT_EQUAL(future.GetValue(), 123);
- future = MakeFuture(345);
- UNIT_ASSERT(future.HasValue());
- UNIT_ASSERT_EQUAL(future.GetValue(), 345);
- }
+ future = MakeFuture(345);
+ UNIT_ASSERT(future.HasValue());
+ UNIT_ASSERT_EQUAL(future.GetValue(), 345);
+ }
Y_UNIT_TEST(ShouldStoreValueVoid) {
- TPromise<void> promise = NewPromise();
- promise.SetValue();
- UNIT_ASSERT(promise.HasValue());
+ TPromise<void> promise = NewPromise();
+ promise.SetValue();
+ UNIT_ASSERT(promise.HasValue());
- TFuture<void> future = promise.GetFuture();
- UNIT_ASSERT(future.HasValue());
+ TFuture<void> future = promise.GetFuture();
+ UNIT_ASSERT(future.HasValue());
- future = MakeFuture();
- UNIT_ASSERT(future.HasValue());
- }
+ future = MakeFuture();
+ UNIT_ASSERT(future.HasValue());
+ }
- struct TTestCallback {
- int Value;
+ struct TTestCallback {
+ int Value;
- TTestCallback(int value)
- : Value(value)
- {
- }
+ TTestCallback(int value)
+ : Value(value)
+ {
+ }
- void Callback(const TFuture<int>& future) {
- Value += future.GetValue();
- }
+ void Callback(const TFuture<int>& future) {
+ Value += future.GetValue();
+ }
- int Func(const TFuture<int>& future) {
- return (Value += future.GetValue());
- }
+ int Func(const TFuture<int>& future) {
+ return (Value += future.GetValue());
+ }
- void VoidFunc(const TFuture<int>& future) {
- future.GetValue();
- }
+ void VoidFunc(const TFuture<int>& future) {
+ future.GetValue();
+ }
- TFuture<int> FutureFunc(const TFuture<int>& future) {
- return MakeFuture(Value += future.GetValue());
- }
+ TFuture<int> FutureFunc(const TFuture<int>& future) {
+ return MakeFuture(Value += future.GetValue());
+ }
- TPromise<void> Signal = NewPromise();
- TFuture<void> FutureVoidFunc(const TFuture<int>& future) {
- future.GetValue();
- return Signal;
- }
- };
+ TPromise<void> Signal = NewPromise();
+ TFuture<void> FutureVoidFunc(const TFuture<int>& future) {
+ future.GetValue();
+ return Signal;
+ }
+ };
Y_UNIT_TEST(ShouldInvokeCallback) {
- TPromise<int> promise = NewPromise<int>();
+ TPromise<int> promise = NewPromise<int>();
- TTestCallback callback(123);
- TFuture<int> future = promise.GetFuture()
- .Subscribe([&](const TFuture<int>& theFuture) { return callback.Callback(theFuture); });
+ TTestCallback callback(123);
+ TFuture<int> future = promise.GetFuture()
+ .Subscribe([&](const TFuture<int>& theFuture) { return callback.Callback(theFuture); });
- promise.SetValue(456);
- UNIT_ASSERT_EQUAL(future.GetValue(), 456);
- UNIT_ASSERT_EQUAL(callback.Value, 123 + 456);
- }
+ promise.SetValue(456);
+ UNIT_ASSERT_EQUAL(future.GetValue(), 456);
+ UNIT_ASSERT_EQUAL(callback.Value, 123 + 456);
+ }
Y_UNIT_TEST(ShouldApplyFunc) {
- TPromise<int> promise = NewPromise<int>();
+ TPromise<int> promise = NewPromise<int>();
- TTestCallback callback(123);
- TFuture<int> future = promise.GetFuture()
+ TTestCallback callback(123);
+ TFuture<int> future = promise.GetFuture()
.Apply([&](const auto& theFuture) { return callback.Func(theFuture); });
- promise.SetValue(456);
- UNIT_ASSERT_EQUAL(future.GetValue(), 123 + 456);
- UNIT_ASSERT_EQUAL(callback.Value, 123 + 456);
- }
+ promise.SetValue(456);
+ UNIT_ASSERT_EQUAL(future.GetValue(), 123 + 456);
+ UNIT_ASSERT_EQUAL(callback.Value, 123 + 456);
+ }
Y_UNIT_TEST(ShouldApplyVoidFunc) {
- TPromise<int> promise = NewPromise<int>();
+ TPromise<int> promise = NewPromise<int>();
- TTestCallback callback(123);
- TFuture<void> future = promise.GetFuture()
+ TTestCallback callback(123);
+ TFuture<void> future = promise.GetFuture()
.Apply([&](const auto& theFuture) { return callback.VoidFunc(theFuture); });
- promise.SetValue(456);
- UNIT_ASSERT(future.HasValue());
- }
+ promise.SetValue(456);
+ UNIT_ASSERT(future.HasValue());
+ }
Y_UNIT_TEST(ShouldApplyFutureFunc) {
- TPromise<int> promise = NewPromise<int>();
+ TPromise<int> promise = NewPromise<int>();
- TTestCallback callback(123);
- TFuture<int> future = promise.GetFuture()
+ TTestCallback callback(123);
+ TFuture<int> future = promise.GetFuture()
.Apply([&](const auto& theFuture) { return callback.FutureFunc(theFuture); });
- promise.SetValue(456);
- UNIT_ASSERT_EQUAL(future.GetValue(), 123 + 456);
- UNIT_ASSERT_EQUAL(callback.Value, 123 + 456);
- }
+ promise.SetValue(456);
+ UNIT_ASSERT_EQUAL(future.GetValue(), 123 + 456);
+ UNIT_ASSERT_EQUAL(callback.Value, 123 + 456);
+ }
Y_UNIT_TEST(ShouldApplyFutureVoidFunc) {
- TPromise<int> promise = NewPromise<int>();
+ TPromise<int> promise = NewPromise<int>();
- TTestCallback callback(123);
- TFuture<void> future = promise.GetFuture()
+ TTestCallback callback(123);
+ TFuture<void> future = promise.GetFuture()
.Apply([&](const auto& theFuture) { return callback.FutureVoidFunc(theFuture); });
- promise.SetValue(456);
- UNIT_ASSERT(!future.HasValue());
+ promise.SetValue(456);
+ UNIT_ASSERT(!future.HasValue());
- callback.Signal.SetValue();
- UNIT_ASSERT(future.HasValue());
- }
+ callback.Signal.SetValue();
+ UNIT_ASSERT(future.HasValue());
+ }
Y_UNIT_TEST(ShouldIgnoreResultIfAsked) {
- TPromise<int> promise = NewPromise<int>();
+ TPromise<int> promise = NewPromise<int>();
- TTestCallback callback(123);
- TFuture<int> future = promise.GetFuture().IgnoreResult().Return(42);
+ TTestCallback callback(123);
+ TFuture<int> future = promise.GetFuture().IgnoreResult().Return(42);
- promise.SetValue(456);
- UNIT_ASSERT_EQUAL(future.GetValue(), 42);
- }
+ promise.SetValue(456);
+ UNIT_ASSERT_EQUAL(future.GetValue(), 42);
+ }
- class TCustomException: public yexception {
- };
+ class TCustomException: public yexception {
+ };
Y_UNIT_TEST(ShouldRethrowException) {
- TPromise<int> promise = NewPromise<int>();
- try {
- ythrow TCustomException();
- } catch (...) {
- promise.SetException(std::current_exception());
- }
-
- UNIT_ASSERT(!promise.HasValue());
- UNIT_ASSERT(promise.HasException());
- UNIT_ASSERT_EXCEPTION(promise.GetValue(), TCustomException);
+ TPromise<int> promise = NewPromise<int>();
+ try {
+ ythrow TCustomException();
+ } catch (...) {
+ promise.SetException(std::current_exception());
+ }
+
+ UNIT_ASSERT(!promise.HasValue());
+ UNIT_ASSERT(promise.HasException());
+ UNIT_ASSERT_EXCEPTION(promise.GetValue(), TCustomException);
UNIT_ASSERT_EXCEPTION(promise.TryRethrow(), TCustomException);
}
@@ -261,36 +261,36 @@ namespace {
Y_UNIT_TEST(ShouldWaitExceptionOrAll) {
- TPromise<void> promise1 = NewPromise();
- TPromise<void> promise2 = NewPromise();
+ TPromise<void> promise1 = NewPromise();
+ TPromise<void> promise2 = NewPromise();
TFuture<void> future = WaitExceptionOrAll(promise1, promise2);
- UNIT_ASSERT(!future.HasValue());
+ UNIT_ASSERT(!future.HasValue());
- promise1.SetValue();
- UNIT_ASSERT(!future.HasValue());
+ promise1.SetValue();
+ UNIT_ASSERT(!future.HasValue());
- promise2.SetValue();
- UNIT_ASSERT(future.HasValue());
- }
+ promise2.SetValue();
+ UNIT_ASSERT(future.HasValue());
+ }
Y_UNIT_TEST(ShouldWaitExceptionOrAllVector) {
- TPromise<void> promise1 = NewPromise();
- TPromise<void> promise2 = NewPromise();
+ TPromise<void> promise1 = NewPromise();
+ TPromise<void> promise2 = NewPromise();
- TVector<TFuture<void>> promises;
- promises.push_back(promise1);
- promises.push_back(promise2);
+ TVector<TFuture<void>> promises;
+ promises.push_back(promise1);
+ promises.push_back(promise2);
TFuture<void> future = WaitExceptionOrAll(promises);
- UNIT_ASSERT(!future.HasValue());
+ UNIT_ASSERT(!future.HasValue());
- promise1.SetValue();
- UNIT_ASSERT(!future.HasValue());
+ promise1.SetValue();
+ UNIT_ASSERT(!future.HasValue());
- promise2.SetValue();
- UNIT_ASSERT(future.HasValue());
- }
+ promise2.SetValue();
+ UNIT_ASSERT(future.HasValue());
+ }
Y_UNIT_TEST(ShouldWaitExceptionOrAllVectorWithValueType) {
TPromise<int> promise1 = NewPromise<int>();
@@ -311,47 +311,47 @@ namespace {
}
Y_UNIT_TEST(ShouldWaitExceptionOrAllList) {
- TPromise<void> promise1 = NewPromise();
- TPromise<void> promise2 = NewPromise();
+ TPromise<void> promise1 = NewPromise();
+ TPromise<void> promise2 = NewPromise();
- std::list<TFuture<void>> promises;
- promises.push_back(promise1);
- promises.push_back(promise2);
+ std::list<TFuture<void>> promises;
+ promises.push_back(promise1);
+ promises.push_back(promise2);
TFuture<void> future = WaitExceptionOrAll(promises);
- UNIT_ASSERT(!future.HasValue());
+ UNIT_ASSERT(!future.HasValue());
- promise1.SetValue();
- UNIT_ASSERT(!future.HasValue());
+ promise1.SetValue();
+ UNIT_ASSERT(!future.HasValue());
- promise2.SetValue();
- UNIT_ASSERT(future.HasValue());
- }
+ promise2.SetValue();
+ UNIT_ASSERT(future.HasValue());
+ }
Y_UNIT_TEST(ShouldWaitExceptionOrAllVectorEmpty) {
- TVector<TFuture<void>> promises;
+ TVector<TFuture<void>> promises;
TFuture<void> future = WaitExceptionOrAll(promises);
- UNIT_ASSERT(future.HasValue());
- }
+ UNIT_ASSERT(future.HasValue());
+ }
Y_UNIT_TEST(ShouldWaitAnyVector) {
- TPromise<void> promise1 = NewPromise();
- TPromise<void> promise2 = NewPromise();
+ TPromise<void> promise1 = NewPromise();
+ TPromise<void> promise2 = NewPromise();
- TVector<TFuture<void>> promises;
- promises.push_back(promise1);
- promises.push_back(promise2);
+ TVector<TFuture<void>> promises;
+ promises.push_back(promise1);
+ promises.push_back(promise2);
- TFuture<void> future = WaitAny(promises);
- UNIT_ASSERT(!future.HasValue());
+ TFuture<void> future = WaitAny(promises);
+ UNIT_ASSERT(!future.HasValue());
- promise1.SetValue();
- UNIT_ASSERT(future.HasValue());
+ promise1.SetValue();
+ UNIT_ASSERT(future.HasValue());
- promise2.SetValue();
- UNIT_ASSERT(future.HasValue());
- }
+ promise2.SetValue();
+ UNIT_ASSERT(future.HasValue());
+ }
Y_UNIT_TEST(ShouldWaitAnyVectorWithValueType) {
@@ -373,112 +373,112 @@ namespace {
}
Y_UNIT_TEST(ShouldWaitAnyList) {
- TPromise<void> promise1 = NewPromise();
- TPromise<void> promise2 = NewPromise();
+ TPromise<void> promise1 = NewPromise();
+ TPromise<void> promise2 = NewPromise();
- std::list<TFuture<void>> promises;
- promises.push_back(promise1);
- promises.push_back(promise2);
+ std::list<TFuture<void>> promises;
+ promises.push_back(promise1);
+ promises.push_back(promise2);
- TFuture<void> future = WaitAny(promises);
- UNIT_ASSERT(!future.HasValue());
+ TFuture<void> future = WaitAny(promises);
+ UNIT_ASSERT(!future.HasValue());
- promise1.SetValue();
- UNIT_ASSERT(future.HasValue());
+ promise1.SetValue();
+ UNIT_ASSERT(future.HasValue());
- promise2.SetValue();
- UNIT_ASSERT(future.HasValue());
- }
+ promise2.SetValue();
+ UNIT_ASSERT(future.HasValue());
+ }
Y_UNIT_TEST(ShouldWaitAnyVectorEmpty) {
- TVector<TFuture<void>> promises;
+ TVector<TFuture<void>> promises;
- TFuture<void> future = WaitAny(promises);
- UNIT_ASSERT(future.HasValue());
- }
+ TFuture<void> future = WaitAny(promises);
+ UNIT_ASSERT(future.HasValue());
+ }
Y_UNIT_TEST(ShouldWaitAny) {
- TPromise<void> promise1 = NewPromise();
- TPromise<void> promise2 = NewPromise();
+ TPromise<void> promise1 = NewPromise();
+ TPromise<void> promise2 = NewPromise();
- TFuture<void> future = WaitAny(promise1, promise2);
- UNIT_ASSERT(!future.HasValue());
+ TFuture<void> future = WaitAny(promise1, promise2);
+ UNIT_ASSERT(!future.HasValue());
- promise1.SetValue();
- UNIT_ASSERT(future.HasValue());
+ promise1.SetValue();
+ UNIT_ASSERT(future.HasValue());
- promise2.SetValue();
- UNIT_ASSERT(future.HasValue());
- }
+ promise2.SetValue();
+ UNIT_ASSERT(future.HasValue());
+ }
Y_UNIT_TEST(ShouldStoreTypesWithoutDefaultConstructor) {
- // compileability test
- struct TRec {
- explicit TRec(int) {
- }
- };
+ // compileability test
+ struct TRec {
+ explicit TRec(int) {
+ }
+ };
- auto promise = NewPromise<TRec>();
- promise.SetValue(TRec(1));
+ auto promise = NewPromise<TRec>();
+ promise.SetValue(TRec(1));
- auto future = MakeFuture(TRec(1));
- const auto& rec = future.GetValue();
- Y_UNUSED(rec);
- }
+ auto future = MakeFuture(TRec(1));
+ const auto& rec = future.GetValue();
+ Y_UNUSED(rec);
+ }
Y_UNIT_TEST(ShouldStoreMovableTypes) {
- // compileability test
- struct TRec : TMoveOnly {
- explicit TRec(int) {
- }
- };
+ // compileability test
+ struct TRec : TMoveOnly {
+ explicit TRec(int) {
+ }
+ };
- auto promise = NewPromise<TRec>();
- promise.SetValue(TRec(1));
+ auto promise = NewPromise<TRec>();
+ promise.SetValue(TRec(1));
- auto future = MakeFuture(TRec(1));
- const auto& rec = future.GetValue();
- Y_UNUSED(rec);
- }
+ auto future = MakeFuture(TRec(1));
+ const auto& rec = future.GetValue();
+ Y_UNUSED(rec);
+ }
Y_UNIT_TEST(ShouldMoveMovableTypes) {
- // compileability test
- struct TRec : TMoveOnly {
- explicit TRec(int) {
- }
- };
+ // compileability test
+ struct TRec : TMoveOnly {
+ explicit TRec(int) {
+ }
+ };
- auto promise = NewPromise<TRec>();
- promise.SetValue(TRec(1));
+ auto promise = NewPromise<TRec>();
+ promise.SetValue(TRec(1));
- auto future = MakeFuture(TRec(1));
- auto rec = future.ExtractValue();
- Y_UNUSED(rec);
- }
+ auto future = MakeFuture(TRec(1));
+ auto rec = future.ExtractValue();
+ Y_UNUSED(rec);
+ }
Y_UNIT_TEST(ShouldNotExtractAfterGet) {
- TPromise<int> promise = NewPromise<int>();
- promise.SetValue(123);
- UNIT_ASSERT(promise.HasValue());
- UNIT_ASSERT_EQUAL(promise.GetValue(), 123);
- UNIT_CHECK_GENERATED_EXCEPTION(promise.ExtractValue(), TFutureException);
- }
+ TPromise<int> promise = NewPromise<int>();
+ promise.SetValue(123);
+ UNIT_ASSERT(promise.HasValue());
+ UNIT_ASSERT_EQUAL(promise.GetValue(), 123);
+ UNIT_CHECK_GENERATED_EXCEPTION(promise.ExtractValue(), TFutureException);
+ }
Y_UNIT_TEST(ShouldNotGetAfterExtract) {
- TPromise<int> promise = NewPromise<int>();
- promise.SetValue(123);
- UNIT_ASSERT(promise.HasValue());
- UNIT_ASSERT_EQUAL(promise.ExtractValue(), 123);
- UNIT_CHECK_GENERATED_EXCEPTION(promise.GetValue(), TFutureException);
- }
+ TPromise<int> promise = NewPromise<int>();
+ promise.SetValue(123);
+ UNIT_ASSERT(promise.HasValue());
+ UNIT_ASSERT_EQUAL(promise.ExtractValue(), 123);
+ UNIT_CHECK_GENERATED_EXCEPTION(promise.GetValue(), TFutureException);
+ }
Y_UNIT_TEST(ShouldNotExtractAfterExtract) {
- TPromise<int> promise = NewPromise<int>();
- promise.SetValue(123);
- UNIT_ASSERT(promise.HasValue());
- UNIT_ASSERT_EQUAL(promise.ExtractValue(), 123);
- UNIT_CHECK_GENERATED_EXCEPTION(promise.ExtractValue(), TFutureException);
- }
+ TPromise<int> promise = NewPromise<int>();
+ promise.SetValue(123);
+ UNIT_ASSERT(promise.HasValue());
+ UNIT_ASSERT_EQUAL(promise.ExtractValue(), 123);
+ UNIT_CHECK_GENERATED_EXCEPTION(promise.ExtractValue(), TFutureException);
+ }
Y_UNIT_TEST(ShouldNotExtractFromSharedDefault) {
UNIT_CHECK_GENERATED_EXCEPTION(MakeFuture<int>().ExtractValue(), TFutureException);
diff --git a/library/cpp/threading/future/legacy_future.h b/library/cpp/threading/future/legacy_future.h
index 6f1eabad73..c699aadf5c 100644
--- a/library/cpp/threading/future/legacy_future.h
+++ b/library/cpp/threading/future/legacy_future.h
@@ -4,79 +4,79 @@
#include "future.h"
#include <util/thread/factory.h>
-
+
#include <functional>
-
+
namespace NThreading {
template <typename TR, bool IgnoreException>
class TLegacyFuture: public IThreadFactory::IThreadAble, TNonCopyable {
- public:
- typedef TR(TFunctionSignature)();
- using TFunctionObjectType = std::function<TFunctionSignature>;
- using TResult = typename TFunctionObjectType::result_type;
+ public:
+ typedef TR(TFunctionSignature)();
+ using TFunctionObjectType = std::function<TFunctionSignature>;
+ using TResult = typename TFunctionObjectType::result_type;
- private:
- TFunctionObjectType Func_;
- TPromise<TResult> Result_;
+ private:
+ TFunctionObjectType Func_;
+ TPromise<TResult> Result_;
THolder<IThreadFactory::IThread> Thread_;
- public:
+ public:
inline TLegacyFuture(const TFunctionObjectType func, IThreadFactory* pool = SystemThreadFactory())
- : Func_(func)
- , Result_(NewPromise<TResult>())
- , Thread_(pool->Run(this))
- {
- }
+ : Func_(func)
+ , Result_(NewPromise<TResult>())
+ , Thread_(pool->Run(this))
+ {
+ }
- inline ~TLegacyFuture() override {
- this->Join();
- }
+ inline ~TLegacyFuture() override {
+ this->Join();
+ }
- inline TResult Get() {
- this->Join();
- return Result_.GetValue();
- }
+ inline TResult Get() {
+ this->Join();
+ return Result_.GetValue();
+ }
- private:
- inline void Join() {
- if (Thread_) {
- Thread_->Join();
- Thread_.Destroy();
- }
+ private:
+ inline void Join() {
+ if (Thread_) {
+ Thread_->Join();
+ Thread_.Destroy();
+ }
}
- template <typename Result, bool IgnoreException_>
- struct TExecutor {
- static void SetPromise(TPromise<Result>& promise, const TFunctionObjectType& func) {
- if (IgnoreException_) {
- try {
- promise.SetValue(func());
- } catch (...) {
- }
- } else {
+ template <typename Result, bool IgnoreException_>
+ struct TExecutor {
+ static void SetPromise(TPromise<Result>& promise, const TFunctionObjectType& func) {
+ if (IgnoreException_) {
+ try {
+ promise.SetValue(func());
+ } catch (...) {
+ }
+ } else {
promise.SetValue(func());
}
}
- };
+ };
- template <bool IgnoreException_>
- struct TExecutor<void, IgnoreException_> {
- static void SetPromise(TPromise<void>& promise, const TFunctionObjectType& func) {
- if (IgnoreException_) {
- try {
- func();
- promise.SetValue();
- } catch (...) {
- }
- } else {
+ template <bool IgnoreException_>
+ struct TExecutor<void, IgnoreException_> {
+ static void SetPromise(TPromise<void>& promise, const TFunctionObjectType& func) {
+ if (IgnoreException_) {
+ try {
+ func();
+ promise.SetValue();
+ } catch (...) {
+ }
+ } else {
func();
promise.SetValue();
}
}
- };
-
- void DoExecute() override {
- TExecutor<TResult, IgnoreException>::SetPromise(Result_, Func_);
+ };
+
+ void DoExecute() override {
+ TExecutor<TResult, IgnoreException>::SetPromise(Result_, Func_);
}
};
diff --git a/library/cpp/threading/future/legacy_future_ut.cpp b/library/cpp/threading/future/legacy_future_ut.cpp
index ff63db1725..96b46ccebf 100644
--- a/library/cpp/threading/future/legacy_future_ut.cpp
+++ b/library/cpp/threading/future/legacy_future_ut.cpp
@@ -4,69 +4,69 @@
namespace NThreading {
Y_UNIT_TEST_SUITE(TLegacyFutureTest) {
- int intf() {
- return 17;
- }
+ int intf() {
+ return 17;
+ }
Y_UNIT_TEST(TestIntFunction) {
- TLegacyFuture<int> f((&intf));
- UNIT_ASSERT_VALUES_EQUAL(17, f.Get());
- }
+ TLegacyFuture<int> f((&intf));
+ UNIT_ASSERT_VALUES_EQUAL(17, f.Get());
+ }
- static int r;
+ static int r;
- void voidf() {
- r = 18;
- }
+ void voidf() {
+ r = 18;
+ }
Y_UNIT_TEST(TestVoidFunction) {
- r = 0;
- TLegacyFuture<> f((&voidf));
- f.Get();
- UNIT_ASSERT_VALUES_EQUAL(18, r);
- }
+ r = 0;
+ TLegacyFuture<> f((&voidf));
+ f.Get();
+ UNIT_ASSERT_VALUES_EQUAL(18, r);
+ }
- struct TSampleClass {
- int mValue;
+ struct TSampleClass {
+ int mValue;
- TSampleClass(int value)
- : mValue(value)
- {
- }
+ TSampleClass(int value)
+ : mValue(value)
+ {
+ }
- int Calc() {
- return mValue + 1;
- }
- };
+ int Calc() {
+ return mValue + 1;
+ }
+ };
Y_UNIT_TEST(TestMethod) {
- TLegacyFuture<int> f11(std::bind(&TSampleClass::Calc, TSampleClass(3)));
- UNIT_ASSERT_VALUES_EQUAL(4, f11.Get());
+ TLegacyFuture<int> f11(std::bind(&TSampleClass::Calc, TSampleClass(3)));
+ UNIT_ASSERT_VALUES_EQUAL(4, f11.Get());
TLegacyFuture<int> f12(std::bind(&TSampleClass::Calc, TSampleClass(3)), SystemThreadFactory());
- UNIT_ASSERT_VALUES_EQUAL(4, f12.Get());
+ UNIT_ASSERT_VALUES_EQUAL(4, f12.Get());
- TSampleClass c(5);
+ TSampleClass c(5);
- TLegacyFuture<int> f21(std::bind(&TSampleClass::Calc, std::ref(c)));
- UNIT_ASSERT_VALUES_EQUAL(6, f21.Get());
+ TLegacyFuture<int> f21(std::bind(&TSampleClass::Calc, std::ref(c)));
+ UNIT_ASSERT_VALUES_EQUAL(6, f21.Get());
TLegacyFuture<int> f22(std::bind(&TSampleClass::Calc, std::ref(c)), SystemThreadFactory());
- UNIT_ASSERT_VALUES_EQUAL(6, f22.Get());
- }
+ UNIT_ASSERT_VALUES_EQUAL(6, f22.Get());
+ }
struct TSomeThreadPool: public IThreadFactory {};
Y_UNIT_TEST(TestFunction) {
- std::function<int()> f((&intf));
+ std::function<int()> f((&intf));
- UNIT_ASSERT_VALUES_EQUAL(17, TLegacyFuture<int>(f).Get());
+ UNIT_ASSERT_VALUES_EQUAL(17, TLegacyFuture<int>(f).Get());
UNIT_ASSERT_VALUES_EQUAL(17, TLegacyFuture<int>(f, SystemThreadFactory()).Get());
- if (false) {
- TSomeThreadPool* q = nullptr;
- TLegacyFuture<int>(f, q); // just check compiles, do not start
- }
+ if (false) {
+ TSomeThreadPool* q = nullptr;
+ TLegacyFuture<int>(f, q); // just check compiles, do not start
+ }
}
}
diff --git a/library/cpp/threading/future/perf/main.cpp b/library/cpp/threading/future/perf/main.cpp
index 5a0690af47..c7da5a51f3 100644
--- a/library/cpp/threading/future/perf/main.cpp
+++ b/library/cpp/threading/future/perf/main.cpp
@@ -7,44 +7,44 @@
using namespace NThreading;
template <typename T>
-void TestAllocPromise(const NBench::NCpu::TParams& iface) {
- for (const auto it : xrange(iface.Iterations())) {
+void TestAllocPromise(const NBench::NCpu::TParams& iface) {
+ for (const auto it : xrange(iface.Iterations())) {
Y_UNUSED(it);
Y_DO_NOT_OPTIMIZE_AWAY(NewPromise<T>());
}
}
template <typename T>
-TPromise<T> SetPromise(T value) {
+TPromise<T> SetPromise(T value) {
auto promise = NewPromise<T>();
promise.SetValue(value);
return promise;
}
template <typename T>
-void TestSetPromise(const NBench::NCpu::TParams& iface, T value) {
- for (const auto it : xrange(iface.Iterations())) {
+void TestSetPromise(const NBench::NCpu::TParams& iface, T value) {
+ for (const auto it : xrange(iface.Iterations())) {
Y_UNUSED(it);
Y_DO_NOT_OPTIMIZE_AWAY(SetPromise(value));
}
}
-Y_CPU_BENCHMARK(AllocPromiseVoid, iface) {
+Y_CPU_BENCHMARK(AllocPromiseVoid, iface) {
TestAllocPromise<void>(iface);
}
-Y_CPU_BENCHMARK(AllocPromiseUI64, iface) {
+Y_CPU_BENCHMARK(AllocPromiseUI64, iface) {
TestAllocPromise<ui64>(iface);
}
-Y_CPU_BENCHMARK(AllocPromiseStroka, iface) {
+Y_CPU_BENCHMARK(AllocPromiseStroka, iface) {
TestAllocPromise<TString>(iface);
}
-Y_CPU_BENCHMARK(SetPromiseUI64, iface) {
+Y_CPU_BENCHMARK(SetPromiseUI64, iface) {
TestSetPromise<ui64>(iface, 1234567890ull);
}
-Y_CPU_BENCHMARK(SetPromiseStroka, iface) {
+Y_CPU_BENCHMARK(SetPromiseStroka, iface) {
TestSetPromise<TString>(iface, "test test test");
}
diff --git a/library/cpp/threading/future/wait/wait-inl.h b/library/cpp/threading/future/wait/wait-inl.h
index 2753d5446c..9d056ff777 100644
--- a/library/cpp/threading/future/wait/wait-inl.h
+++ b/library/cpp/threading/future/wait/wait-inl.h
@@ -2,10 +2,10 @@
#if !defined(INCLUDE_FUTURE_INL_H)
#error "you should never include wait-inl.h directly"
-#endif // INCLUDE_FUTURE_INL_H
+#endif // INCLUDE_FUTURE_INL_H
namespace NThreading {
- namespace NImpl {
+ namespace NImpl {
template <typename TContainer>
TVector<TFuture<void>> ToVoidFutures(const TContainer& futures) {
TVector<TFuture<void>> voidFutures;
@@ -17,19 +17,19 @@ namespace NThreading {
return voidFutures;
}
- }
+ }
template <typename TContainer>
[[nodiscard]] NImpl::EnableGenericWait<TContainer> WaitAll(const TContainer& futures) {
return WaitAll(NImpl::ToVoidFutures(futures));
}
- template <typename TContainer>
+ template <typename TContainer>
[[nodiscard]] NImpl::EnableGenericWait<TContainer> WaitExceptionOrAll(const TContainer& futures) {
return WaitExceptionOrAll(NImpl::ToVoidFutures(futures));
}
- template <typename TContainer>
+ template <typename TContainer>
[[nodiscard]] NImpl::EnableGenericWait<TContainer> WaitAny(const TContainer& futures) {
return WaitAny(NImpl::ToVoidFutures(futures));
}
diff --git a/library/cpp/threading/future/wait/wait.cpp b/library/cpp/threading/future/wait/wait.cpp
index a173833a7f..e0a1c3bbd3 100644
--- a/library/cpp/threading/future/wait/wait.cpp
+++ b/library/cpp/threading/future/wait/wait.cpp
@@ -31,13 +31,13 @@ namespace NThreading {
TWaitGroup<WaitPolicy> wg;
for (const auto& fut : futures) {
wg.Add(fut);
- }
+ }
return std::move(wg).Finish();
}
- }
+ }
- ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
TFuture<void> WaitAll(const TFuture<void>& f1) {
return WaitGeneric<TWaitPolicy::TAll>(f1);
@@ -56,25 +56,25 @@ namespace NThreading {
TFuture<void> WaitExceptionOrAll(const TFuture<void>& f1) {
return WaitGeneric<TWaitPolicy::TExceptionOrAll>(f1);
- }
+ }
TFuture<void> WaitExceptionOrAll(const TFuture<void>& f1, const TFuture<void>& f2) {
return WaitGeneric<TWaitPolicy::TExceptionOrAll>(f1, f2);
- }
+ }
TFuture<void> WaitExceptionOrAll(TArrayRef<const TFuture<void>> futures) {
return WaitGeneric<TWaitPolicy::TExceptionOrAll>(futures);
}
- ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
TFuture<void> WaitAny(const TFuture<void>& f1) {
return WaitGeneric<TWaitPolicy::TAny>(f1);
- }
+ }
TFuture<void> WaitAny(const TFuture<void>& f1, const TFuture<void>& f2) {
return WaitGeneric<TWaitPolicy::TAny>(f1, f2);
- }
+ }
TFuture<void> WaitAny(TArrayRef<const TFuture<void>> futures) {
return WaitGeneric<TWaitPolicy::TAny>(futures);
diff --git a/library/cpp/threading/future/wait/wait.h b/library/cpp/threading/future/wait/wait.h
index 6ff7d57baa..60ec5b6a63 100644
--- a/library/cpp/threading/future/wait/wait.h
+++ b/library/cpp/threading/future/wait/wait.h
@@ -25,16 +25,16 @@ namespace NThreading {
[[nodiscard]] TFuture<void> WaitExceptionOrAll(const TFuture<void>& f1);
[[nodiscard]] TFuture<void> WaitExceptionOrAll(const TFuture<void>& f1, const TFuture<void>& f2);
[[nodiscard]] TFuture<void> WaitExceptionOrAll(TArrayRef<const TFuture<void>> futures);
- template <typename TContainer>
+ template <typename TContainer>
[[nodiscard]] NImpl::EnableGenericWait<TContainer> WaitExceptionOrAll(const TContainer& futures);
- // waits for any future
+ // waits for any future
[[nodiscard]] TFuture<void> WaitAny(const TFuture<void>& f1);
[[nodiscard]] TFuture<void> WaitAny(const TFuture<void>& f1, const TFuture<void>& f2);
[[nodiscard]] TFuture<void> WaitAny(TArrayRef<const TFuture<void>> futures);
- template <typename TContainer>
+ template <typename TContainer>
[[nodiscard]] NImpl::EnableGenericWait<TContainer> WaitAny(const TContainer& futures);
-}
+}
#define INCLUDE_FUTURE_INL_H
#include "wait-inl.h"