13 #ifndef __PROCESS_FUTURE_HPP__
14 #define __PROCESS_FUTURE_HPP__
23 #include <type_traits>
27 #include <glog/logging.h>
124 bool operator<(const Future<T>& that)
const;
154 const T&
get()
const;
158 const std::string&
failure()
const;
181 template <
typename F>
188 template <
typename F>
195 template <
typename F>
202 template <
typename F>
209 template <
typename F>
216 template <
typename F>
219 return onAny(std::move(deferred)
233 struct LessPrefer {};
234 struct Prefer : LessPrefer {};
237 const Future<T>&
onReady(F&&
f, Prefer)
const
258 typename =
typename result_of<
typename std::enable_if<
261 const Future<T>&
onReady(F&&
f, LessPrefer)
const
273 const Future<T>&
onFailed(F&&
f, Prefer)
const
278 std::move(
f)(message);
288 typename =
typename result_of<
typename std::enable_if<
291 const Future<T>&
onFailed(F&&
f, LessPrefer)
const
302 template <
typename F,
typename =
typename result_of<F(const Future<T>&)>::type>
303 const Future<T>&
onAny(F&&
f, Prefer)
const
308 std::move(
f)(future);
318 typename =
typename result_of<
typename std::enable_if<
321 const Future<T>&
onAny(F&&
f, LessPrefer)
const
333 template <
typename F>
341 std::forward<F>(
f))));
344 template <
typename F>
352 std::forward<F>(
f))));
355 template <
typename F>
358 return onReady(std::forward<F>(
f), Prefer());
361 template <
typename F>
364 return onFailed(std::forward<F>(
f), Prefer());
367 template <
typename F>
375 std::forward<F>(
f))));
378 template <
typename F>
381 return onAny(std::forward<F>(
f), Prefer());
387 template <
typename X>
390 template <
typename X>
393 template <
typename X>
400 template <
typename X>
424 typename X =
typename internal::unwrap<
425 typename result_of<
typename std::enable_if<
428 Future<X>
then(_Deferred<F>&&
f, LessPrefer)
const
434 Future<X>
then(F&&
f, Prefer)
const
444 typename X =
typename internal::unwrap<
445 typename result_of<
typename std::enable_if<
448 Future<X>
then(F&&
f, LessPrefer)
const
463 template <
typename F>
466 -> decltype(this->
then(std::forward<F>(
f), Prefer()))
467 #endif // __WINDOWS__
469 return then(std::forward<F>(
f), Prefer());
474 template <
typename F>
477 template <
typename F>
512 template <
typename U>
516 template <
typename U>
517 friend std::ostream& operator<<(std::ostream&, const Future<U>&);
532 void clearAllCallbacks();
534 std::atomic_flag lock = ATOMIC_FLAG_INIT;
546 std::vector<AbandonedCallback> onAbandonedCallbacks;
547 std::vector<DiscardCallback> onDiscardCallbacks;
548 std::vector<ReadyCallback> onReadyCallbacks;
549 std::vector<FailedCallback> onFailedCallbacks;
550 std::vector<DiscardedCallback> onDiscardedCallbacks;
551 std::vector<AnyCallback> onAnyCallbacks;
593 bool abandon(
bool propagating =
false);
597 bool set(
const T& _t);
600 template <
typename U>
605 bool fail(
const std::string& _message);
607 std::shared_ptr<Data> data;
616 template <
typename C,
typename... Arguments>
617 void run(std::vector<C>&& callbacks, Arguments&&... arguments)
619 for (
size_t i = 0; i < callbacks.size(); ++i) {
620 std::move(callbacks[i])(std::forward<Arguments>(arguments)...);
629 template <
typename T>
640 std::weak_ptr<typename Future<T>::Data> data;
644 template <
typename T>
646 : data(future.data) {}
649 template <
typename T>
653 future.data = data.lock();
692 template <
typename U>
698 template <
typename T>
709 bool set(
const T& _t);
713 bool fail(
const std::string& message);
719 template <
typename U>
721 template <
typename U>
724 template <
typename U>
743 template <
typename T>
752 template <
typename T>
766 template <
typename T>
775 template <
typename T>
780 f.data->abandoned =
false;
784 template <
typename T>
789 template <
typename T>
803 template <
typename T>
805 :
f(std::move(that.
f)) {}
808 template <
typename T>
811 if (!
f.data->associated) {
818 template <
typename T>
821 return _set(std::move(t));
825 template <
typename T>
832 template <
typename T>
833 template <
typename U>
836 if (!
f.data->associated) {
837 return f.set(std::forward<U>(u));
843 template <
typename T>
846 return associate(future);
850 template <
typename T>
853 bool associated =
false;
855 synchronized (
f.data->lock) {
861 associated =
f.data->associated =
true;
901 template <
typename T>
904 if (!
f.data->associated) {
905 return f.fail(message);
911 template <
typename T>
921 template <
typename T>
928 template <
typename X>
935 template <
typename T>
942 template <
typename X>
949 template <
typename T>
955 assert(!
promise->future().isFailed());
957 if (
promise->future().isPending()) {
971 template <
typename T>
976 promise->future().onDiscard(
979 foreach (
const Future<T>& future, futures) {
985 return promise->future();
989 template <
typename T>
998 template <
typename T>
1007 template <
typename T>
1010 bool result =
false;
1012 synchronized (future.data->lock) {
1013 if (future.data->state == Future<T>::PENDING) {
1014 future.data->state = Future<T>::DISCARDED;
1028 internal::run(std::move(future.data->onDiscardedCallbacks));
1029 internal::run(std::move(future.data->onAnyCallbacks), future);
1031 future.data->clearAllCallbacks();
1038 template <
typename T>
1042 future.fail(message);
1047 template <
typename T>
1056 template <
typename T>
1057 void Future<T>::Data::clearAllCallbacks()
1059 onAbandonedCallbacks.clear();
1060 onAnyCallbacks.clear();
1061 onDiscardCallbacks.clear();
1062 onDiscardedCallbacks.clear();
1063 onFailedCallbacks.clear();
1064 onReadyCallbacks.clear();
1068 template <
typename T>
1072 data->abandoned =
true;
1076 template <
typename T>
1084 template <
typename T>
1085 template <
typename U>
1093 template <
typename T>
1101 template <
typename T>
1109 template <
typename T>
1111 : data(that.data) {}
1114 template <
typename T>
1116 : data(std::move(that.data)) {}
1119 template <
typename T>
1131 template <
typename T>
1133 : data(t.isSome() ? t->data : std::shared_ptr<Data>(new Data()))
1141 template <
typename T>
1144 if (
this != &that) {
1151 template <
typename T>
1154 return data == that.data;
1158 template <
typename T>
1161 return !(*
this == that);
1165 template <
typename T>
1168 return data < that.data;
1172 template <
typename T>
1175 bool result =
false;
1177 std::vector<DiscardCallback> callbacks;
1178 synchronized (data->lock) {
1179 if (!data->discard && data->state == PENDING) {
1180 result = data->discard =
true;
1182 callbacks.swap(data->onDiscardCallbacks);
1197 template <
typename T>
1200 bool result =
false;
1202 std::vector<AbandonedCallback> callbacks;
1203 synchronized (data->lock) {
1204 if (!data->abandoned &&
1205 data->state == PENDING &&
1206 (!data->associated || propagating)) {
1207 result = data->abandoned =
true;
1209 callbacks.swap(data->onAbandonedCallbacks);
1223 template <
typename T>
1226 return data->state == PENDING;
1230 template <
typename T>
1233 return data->state == READY;
1237 template <
typename T>
1240 return data->state == DISCARDED;
1244 template <
typename T>
1247 return data->state == FAILED;
1251 template <
typename T>
1254 return data->abandoned;
1258 template <
typename T>
1261 return data->discard;
1265 namespace internal {
1275 template <
typename T>
1294 synchronized (data->lock) {
1295 if (data->state == PENDING) {
1302 return latch->
await(duration);
1309 template <
typename T>
1316 CHECK(!isPending()) <<
"Future was in PENDING after await()";
1319 CHECK(!isFailed()) <<
"Future::get() but state == FAILED: " << failure();
1320 CHECK(!isDiscarded()) <<
"Future::get() but state == DISCARDED";
1323 assert(data->result.isSome());
1324 return data->result.get();
1328 template <
typename T>
1335 template <
typename T>
1338 if (data->state != FAILED) {
1339 ABORT(
"Future::failure() but state != FAILED");
1343 return data->result.error();
1347 template <
typename T>
1352 synchronized (data->lock) {
1353 if (data->abandoned) {
1355 }
else if (data->state == PENDING) {
1356 data->onAbandonedCallbacks.emplace_back(std::move(callback));
1362 std::move(callback)();
1369 template <
typename T>
1374 synchronized (data->lock) {
1375 if (data->discard) {
1377 }
else if (data->state == PENDING) {
1378 data->onDiscardCallbacks.emplace_back(std::move(callback));
1384 std::move(callback)();
1391 template <
typename T>
1396 synchronized (data->lock) {
1397 if (data->state == READY) {
1399 }
else if (data->state == PENDING) {
1400 data->onReadyCallbacks.emplace_back(std::move(callback));
1406 std::move(callback)(data->result.get());
1413 template <
typename T>
1418 synchronized (data->lock) {
1419 if (data->state == FAILED) {
1421 }
else if (data->state == PENDING) {
1422 data->onFailedCallbacks.emplace_back(std::move(callback));
1428 std::move(callback)(data->result.error());
1435 template <
typename T>
1440 synchronized (data->lock) {
1441 if (data->state == DISCARDED) {
1443 }
else if (data->state == PENDING) {
1444 data->onDiscardedCallbacks.emplace_back(std::move(callback));
1450 std::move(callback)();
1457 template <
typename T>
1462 synchronized (data->lock) {
1463 if (data->state == PENDING) {
1464 data->onAnyCallbacks.emplace_back(std::move(callback));
1472 std::move(callback)(*this);
1478 namespace internal {
1483 template <
typename T,
typename X>
1502 template <
typename T,
typename X>
1521 template <
typename T>
1529 promise->associate(std::move(
f)(future));
1536 template <
typename T>
1539 const std::shared_ptr<Latch>& latch,
1544 if (latch->trigger()) {
1558 promise->associate(std::move(*
f)(future));
1563 template <
typename T>
1565 const std::shared_ptr<Latch>& latch,
1571 if (latch->trigger()) {
1590 template <
typename T>
1591 template <
typename X>
1598 &internal::thenf<T, X>, std::move(
f), std::move(promise), lambda::_1);
1600 onAny(std::move(
thenf));
1602 onAbandoned([=]()
mutable {
1614 template <
typename T>
1615 template <
typename X>
1622 &internal::then<T, X>, std::move(
f), std::move(promise), lambda::_1);
1624 onAny(std::move(
then));
1626 onAbandoned([=]()
mutable {
1638 template <
typename T>
1639 template <
typename F>
1646 typedef decltype(std::move(
f)(future)) R;
1648 std::shared_ptr<lambda::CallableOnce<R(const Future<T>&)>> callable(
1658 synchronized (promise->f.data->lock) {
1659 promise->f.data->discard =
false;
1662 promise->set(std::move(*callable)(future));
1664 promise->associate(future);
1670 synchronized (promise->f.data->lock) {
1671 promise->f.data->discard =
false;
1673 promise->set(std::move(*callable)(future));
1681 return promise->future();
1685 template <
typename T>
1693 &internal::repair<T>, std::move(
f), std::move(promise), lambda::_1));
1695 onAbandoned([=]()
mutable {
1707 template <
typename T>
1715 std::shared_ptr<Latch> latch(
new Latch());
1734 std::shared_ptr<F> callable(
new F(std::move(
f)));
1748 lambda::bind(&internal::expired<T>, callable, latch, promise, timer,
1751 onAny(
lambda::bind(&internal::after<T>, latch, promise, timer, lambda::_1));
1754 promise->future().abandon();
1759 promise->future().onDiscard(
1762 return promise->future();
1766 template <
typename T>
1769 return _set(std::move(t));
1773 template <
typename T>
1780 template <
typename T>
1781 template <
typename U>
1782 bool Future<T>::_set(U&& u)
1784 bool result =
false;
1786 synchronized (data->lock) {
1787 if (data->state == PENDING) {
1788 data->result = std::forward<U>(u);
1789 data->state = READY;
1800 std::shared_ptr<typename Future<T>::Data>
copy = data;
1801 internal::run(std::move(copy->onReadyCallbacks), copy->result.get());
1804 copy->clearAllCallbacks();
1811 template <
typename T>
1812 bool Future<T>::fail(
const std::string& _message)
1814 bool result =
false;
1816 synchronized (data->lock) {
1817 if (data->state == PENDING) {
1819 data->state = FAILED;
1830 std::shared_ptr<typename Future<T>::Data> copy = data;
1831 internal::run(std::move(copy->onFailedCallbacks), copy->result.error());
1834 copy->clearAllCallbacks();
1841 template <
typename T>
1842 std::ostream& operator<<(std::ostream& stream, const Future<T>& future)
1844 const std::string suffix = future.data->discard ?
" (with discard)" :
"";
1846 switch (future.data->state) {
1848 if (future.data->abandoned) {
1849 return stream <<
"Abandoned" << suffix;
1851 return stream <<
"Pending" << suffix;
1856 return stream <<
"Ready" << suffix;
1859 return stream <<
"Failed" << suffix <<
": " << future.
failure();
1862 return stream <<
"Discarded" << suffix;
1870 template <
typename T>
1882 template <
typename T>
1886 promise->fail(failure);
1894 template <
typename T>
1906 template <
typename T>
1910 if (promise->future() == future) {
1912 promises->erase(promise);
1940 template <
typename T>
1947 promise->associate(future);
1962 template <
typename F>
1967 typename std::enable_if<
1968 std::is_constructible<F, G>::value,
int>
::type = 0>
1971 template <
typename... Args>
1973 -> decltype(std::declval<F&>()(std::forward<Args>(args)...))
1976 typename std::decay<decltype(f(std::forward<Args>(args)...))>::
type;
1980 "Expecting Future<T> to be returned from undiscarded(...)");
2004 typename std::enable_if<
2015 #endif // __PROCESS_FUTURE_HPP__
void select(const Future< T > &future, std::shared_ptr< Promise< Future< T >>> promise)
Definition: future.hpp:950
bool isReady() const
Definition: future.hpp:1231
WeakFuture(const Future< T > &future)
Definition: future.hpp:645
std::string strerror(int errno_)
A thread-safe version of strerror.
Definition: strerror.hpp:30
Definition: errorbase.hpp:35
Definition: option.hpp:28
#define ABORT(...)
Definition: abort.hpp:40
F && f
Definition: defer.hpp:270
const Future< T > & onAny(F &&f) const
Definition: future.hpp:379
lambda::CallableOnce< void()> DiscardedCallback
Definition: future.hpp:166
const T & get() const
Definition: future.hpp:1310
bool set(const T &_t)
Definition: future.hpp:826
T type
Definition: future.hpp:938
Failure(const std::string &_message)
Definition: future.hpp:666
bool pending(int signal)
Definition: signals.hpp:50
Future< T > type
Definition: future.hpp:924
bool fail(const std::string &message)
Definition: future.hpp:902
Definition: future.hpp:664
void awaited(Owned< Latch > latch)
Definition: future.hpp:1267
const Future< T > & onDiscarded(F &&f) const
Definition: future.hpp:368
ErrnoFailure(const std::string &message)
Definition: future.hpp:680
lambda::CallableOnce< void()> DiscardCallback
Definition: future.hpp:163
static bool cancel(const Timer &timer)
const Future< T > & onDiscard(DiscardCallback &&callback) const
Definition: future.hpp:1370
internal::Partial< typename std::decay< F >::type, typename std::decay< Args >::type...> partial(F &&f, Args &&...args)
Definition: lambda.hpp:291
bool await(const Duration &duration=Seconds(-1)) const
Definition: future.hpp:1276
X type
Definition: future.hpp:945
const Future< T > & onFailed(FailedCallback &&callback) const
Definition: future.hpp:1414
const Future< T > & onFailed(F &&f) const
Definition: future.hpp:362
#define CHECK_ERROR(expression)
Definition: check.hpp:52
bool operator!=(const Future< T > &that) const
Definition: future.hpp:1159
void thenf(lambda::CallableOnce< Future< X >(const T &)> &&f, std::unique_ptr< Promise< X >> promise, const Future< T > &future)
Definition: future.hpp:1484
bool discard()
Definition: future.hpp:1173
UndiscardableDecorator(G &&g)
Definition: future.hpp:1969
void expired(const std::shared_ptr< lambda::CallableOnce< Future< T >(const Future< T > &)>> &f, const std::shared_ptr< Latch > &latch, const std::shared_ptr< Promise< T >> &promise, const std::shared_ptr< Option< Timer >> &timer, const Future< T > &future)
Definition: future.hpp:1537
void failPromises(std::set< Promise< T > * > *promises, const std::string &failure)
Definition: future.hpp:1883
Future< T > & operator=(const Future< T > &that)
Definition: future.hpp:1142
Future< T > recover(_Deferred< F > &&deferred) const
Definition: future.hpp:478
Definition: duration.hpp:32
Definition: result.hpp:40
bool isPending() const
Definition: future.hpp:1224
Definition: future.hpp:66
bool isSome() const
Definition: option.hpp:115
bool operator==(const Future< T > &that) const
Definition: future.hpp:1152
Try< bool > set(const std::string &_link, unsigned int flags)
Definition: internal.hpp:125
Definition: future.hpp:63
void after(const std::shared_ptr< Latch > &latch, const std::shared_ptr< Promise< T >> &promise, const std::shared_ptr< Option< Timer >> &timer, const Future< T > &future)
Definition: future.hpp:1564
#define CHECK_SOME(expression)
Definition: check.hpp:44
bool isDiscarded() const
Definition: future.hpp:1238
ErrnoFailure()
Definition: future.hpp:675
void discardPromises(std::set< Promise< T > * > *promises)
Definition: future.hpp:1895
const Future< T > & onDiscarded(DiscardedCallback &&callback) const
Definition: future.hpp:1436
const Future< T > & onFailed(_Deferred< F > &&deferred) const
Definition: future.hpp:203
const Future< T > & onDiscard(_Deferred< F > &&deferred) const
Definition: future.hpp:189
F f
Definition: future.hpp:1985
const Future< T > & onAny(AnyCallback &&callback) const
Definition: future.hpp:1458
Definition: deferred.hpp:64
lambda::CallableOnce< void(const T &)> ReadyCallback
Definition: future.hpp:164
Definition: duration.hpp:259
bool associate(const Future< T > &future)
Definition: future.hpp:851
void discard(WeakFuture< T > reference)
Definition: future.hpp:753
Future< Future< T > > select(const std::set< Future< T >> &futures)
Definition: future.hpp:972
Definition: traits.hpp:17
Definition: future.hpp:73
Future< X > then(lambda::CallableOnce< X()> f) const
Definition: future.hpp:401
const Future< T > & onReady(F &&f) const
Definition: future.hpp:356
const Future< T > & onAbandoned(AbandonedCallback &&callback) const
Definition: future.hpp:1348
void repair(lambda::CallableOnce< Future< T >(const Future< T > &)> &&f, std::unique_ptr< Promise< T >> promise, const Future< T > &future)
Definition: future.hpp:1522
bool isSome() const
Definition: try.hpp:70
Failure(const Error &error)
Definition: future.hpp:667
const Future< T > & onDiscard(F &&f) const
Definition: future.hpp:345
Definition: future.hpp:673
const T & get() const &
Definition: option.hpp:118
Protocol< PromiseRequest, PromiseResponse > promise
Future< X > type
Definition: future.hpp:931
Future< T > repair(lambda::CallableOnce< Future< T >(const Future< T > &)> f) const
Definition: future.hpp:1686
Definition: future.hpp:78
void discard(const std::set< Future< T >> &futures)
Definition: future.hpp:990
static Try error(const E &e)
Definition: try.hpp:42
Future< R > run(R(*method)())
Definition: run.hpp:55
Try< std::vector< Entry > > list(const std::string &hierarchy, const std::string &cgroup)
Future< X > then(lambda::CallableOnce< Future< X >(const T &)> f) const
Definition: future.hpp:1592
Future< T > undiscardable(const Future< T > &future)
Definition: future.hpp:1941
void run(std::vector< C > &&callbacks, Arguments &&...arguments)
Definition: future.hpp:617
Future< std::list< Future< T > > > await(const std::list< Future< T >> &futures)
Definition: collect.hpp:305
lambda::CallableOnce< void()> AbandonedCallback
Definition: future.hpp:162
bool operator<(const Future< T > &that) const
Definition: future.hpp:1166
Future()
Definition: future.hpp:1069
Result< Process > process(pid_t pid)
Definition: freebsd.hpp:30
Future< X > then(lambda::CallableOnce< Future< X >()> f) const
Definition: future.hpp:394
std::string error(const std::string &msg, uint32_t code)
lambda::CallableOnce< void(const std::string &)> FailedCallback
Definition: future.hpp:165
void then(lambda::CallableOnce< X(const T &)> &&f, std::unique_ptr< Promise< X >> promise, const Future< T > &future)
Definition: future.hpp:1503
const int code
Definition: future.hpp:686
Promise()
Definition: future.hpp:776
Future< T > future() const
Definition: future.hpp:912
ErrnoFailure(int _code, const std::string &message)
Definition: future.hpp:683
const std::string message
Definition: future.hpp:669
bool await(const Duration &duration=Seconds(-1))
auto then(F &&f) const -> decltype(this->then(std::forward< F >(f), Prefer()))
Definition: future.hpp:464
bool discard()
Definition: future.hpp:809
Try< uint32_t > type(const std::string &path)
Future< T > after(const Duration &duration, lambda::CallableOnce< Future< T >(const Future< T > &)> f) const
Definition: future.hpp:1708
const Future< T > & onAbandoned(F &&f) const
Definition: future.hpp:334
bool isAbandoned() const
Definition: future.hpp:1252
ErrnoFailure(int _code)
Definition: future.hpp:677
void discarded(Future< U > future)
const Future< T > & onAny(_Deferred< F > &&deferred) const
Definition: future.hpp:217
static Timer timer(const Duration &duration, const lambda::function< void()> &thunk)
const Future< T > & onDiscarded(_Deferred< F > &&deferred) const
Definition: future.hpp:210
Try< Nothing > bind(int_fd s, const Address &address)
Definition: network.hpp:46
const std::string & failure() const
Definition: future.hpp:1336
Option< Future< T > > get() const
Definition: future.hpp:650
const Future< T > & onReady(_Deferred< F > &&deferred) const
Definition: future.hpp:196
Definition: future.hpp:1963
static Future< T > failed(const std::string &message)
Definition: future.hpp:1039
bool hasDiscard() const
Definition: future.hpp:1259
T copy(const T &t)
Definition: utils.hpp:21
const Future< T > & onReady(ReadyCallback &&callback) const
Definition: future.hpp:1392
const T & get() const
Definition: try.hpp:73
virtual ~Promise()
Definition: future.hpp:790
const Future< T > & onAbandoned(_Deferred< F > &&deferred) const
Definition: future.hpp:182
Definition: lambda.hpp:341
auto operator()(Args &&...args) -> decltype(std::declval< F & >()(std::forward< Args >(args)...))
Definition: future.hpp:1972
void setPromises(std::set< Promise< T > * > *promises, const T &t)
Definition: future.hpp:1871
const T * operator->() const
Definition: future.hpp:1329
bool isFailed() const
Definition: future.hpp:1245
Definition: future.hpp:57
Future< T > recover(F &&f) const
Definition: future.hpp:1640