3 #include <boost/thread/mutex.hpp>
4 #include <boost/function.hpp>
5 #include <boost/optional.hpp>
13 auto flatten(std::future<T>&& f) -> std::future<typename std::decay<decltype(f.get().get())>::type>
15 auto shared_f = f.share();
16 return std::async(std::launch::deferred, [=]() mutable -> typename std::decay<decltype(f.get().get())>::type
18 return shared_f.get().get();
23 bool is_ready(const F& future)
25 return future.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
29 * A utility that helps the producer side of a future when the task is not
30 * able to complete immediately but there are known retry points in the code.
36 typedef boost::function<boost::optional<R> ()> func_type;
38 retry_task() : done_(false) {}
41 * Reset the state with a new task. If the previous task has not completed
42 * the old one will be discarded.
44 * @param func The function that tries to calculate future result. If the
45 * optional return value is set the future is marked as ready.
47 void set_task(const func_type& func)
49 boost::unique_lock<boost::mutex> lock(mutex_);
53 promise_ = std::promise<R>();
57 * Take ownership of the future for the current task. Cannot only be called
62 std::future<R> get_future()
64 boost::unique_lock<boost::mutex> lock(mutex_);
66 return promise_.get_future();
70 * Call this when it is guaranteed or probable that the task will be able
73 * @return true if the task completed (the future will have a result).
77 boost::unique_lock<boost::mutex> lock(mutex_);
79 return try_completion_internal();
83 * Call this when it is certain that the result should be ready, and if not
84 * it should be regarded as an unrecoverable error (retrying again would
85 * be useless), so the future will be marked as failed.
87 * @param exception The exception to mark the future with *if* the task
91 void try_or_fail(const E& exception)
93 boost::unique_lock<boost::mutex> lock(mutex_);
95 if (!try_completion_internal())
103 CASPAR_LOG_CURRENT_EXCEPTION();
104 promise_.set_exception(std::current_exception());
110 bool try_completion_internal()
118 boost::optional<R> result;
126 CASPAR_LOG_CURRENT_EXCEPTION();
127 promise_.set_exception(std::current_exception());
135 promise_.set_value(*result);
144 std::promise<R> promise_;
149 * Wrap a value in a future with an already known result.
151 * Useful when the result of an operation is already known at the time of
154 * @param value The r-value to wrap.
156 * @return The future with the result set.
159 std::future<R> make_ready_future(R&& value)
165 return p.get_future();
168 static std::future<void> make_ready_future()
170 std::promise<void> p;
174 return p.get_future();