10#include <userver/engine/condition_variable.hpp>
11#include <userver/engine/exception.hpp>
12#include <userver/engine/task/cancel.hpp>
13#include <userver/utils/assert.hpp>
14#include <userver/utils/result_store.hpp>
16USERVER_NAMESPACE_BEGIN
22class LazyValue final {
24 explicit LazyValue(std::function<T()> f)
37 std::function<T()> f_;
38 std::atomic<
bool> started_{
false};
39 utils::ResultStore<T> result_;
41 engine::ConditionVariable cv_finished_;
42 engine::Mutex m_finished_;
43 std::atomic<
bool> finished_{
false};
52 auto old = started_.exchange(
true);
55 result_.SetValue(f_());
57 const std::lock_guard lock(m_finished_);
61 result_.SetException(std::current_exception());
63 const std::lock_guard lock(m_finished_);
69 std::unique_lock lock(m_finished_);
70 auto rc = cv_finished_.Wait(lock, [
this]() {
return finished_.load(); });
72 throw engine::WaitInterruptedException(engine::current_task::CancellationReason());