diff options
author | Anton Samokhvalov <pg83@yandex.ru> | 2022-02-10 16:45:15 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:15 +0300 |
commit | 72cb13b4aff9bc9cf22e49251bc8fd143f82538f (patch) | |
tree | da2c34829458c7d4e74bdfbdf85dff449e9e7fb8 /library/cpp/threading/future | |
parent | 778e51ba091dc39e7b7fcab2b9cf4dbedfb6f2b5 (diff) | |
download | ydb-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.h | 14 | ||||
-rw-r--r-- | library/cpp/threading/future/async_ut.cpp | 48 | ||||
-rw-r--r-- | library/cpp/threading/future/core/future-inl.h | 1200 | ||||
-rw-r--r-- | library/cpp/threading/future/core/future.h | 240 | ||||
-rw-r--r-- | library/cpp/threading/future/future_ut.cpp | 474 | ||||
-rw-r--r-- | library/cpp/threading/future/legacy_future.h | 104 | ||||
-rw-r--r-- | library/cpp/threading/future/legacy_future_ut.cpp | 78 | ||||
-rw-r--r-- | library/cpp/threading/future/perf/main.cpp | 20 | ||||
-rw-r--r-- | library/cpp/threading/future/wait/wait-inl.h | 10 | ||||
-rw-r--r-- | library/cpp/threading/future/wait/wait.cpp | 16 | ||||
-rw-r--r-- | library/cpp/threading/future/wait/wait.h | 8 |
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" |