diff --git a/include/ircd/ctx/future.h b/include/ircd/ctx/future.h index 42ad58832..ebed419a7 100644 --- a/include/ircd/ctx/future.h +++ b/include/ircd/ctx/future.h @@ -58,6 +58,8 @@ class ircd::ctx::future T get(); operator T() { return get(); } + void then(decltype(shared_state::callback)); + future(); future(promise &promise); }; @@ -82,6 +84,8 @@ class ircd::ctx::future template future_status wait(const duration &d) const; void wait() const; + void then(decltype(shared_state::callback)); + future(); future(promise &promise); }; @@ -136,6 +140,21 @@ ircd::ctx::future::future(promise &promise) { } +template +void +ircd::ctx::future::then(decltype(shared_state::callback) cb) +{ + assert(valid()); + st->callback = std::move(cb); +} + +inline void +ircd::ctx::future::then(decltype(shared_state::callback) cb) +{ + assert(valid()); + st->callback = std::move(cb); +} + template T ircd::ctx::future::get() diff --git a/include/ircd/ctx/promise.h b/include/ircd/ctx/promise.h index c38ddb2fd..74f8e5c59 100644 --- a/include/ircd/ctx/promise.h +++ b/include/ircd/ctx/promise.h @@ -147,6 +147,10 @@ ircd::ctx::promise::set_value(T&& val) st->val = std::move(val); st->finished = true; st->cond.notify_all(); + if(st->callback) ircd::post([st(st)] + { + st->callback(st->eptr, st->val); + }); } inline void @@ -156,6 +160,10 @@ ircd::ctx::promise::set_value() assert(!finished()); st->finished = true; st->cond.notify_all(); + if(st->callback) ircd::post([st(st)] + { + st->callback(st->eptr); + }); } template @@ -167,6 +175,10 @@ ircd::ctx::promise::set_value(const T &val) st->val = val; st->finished = true; st->cond.notify_all(); + if(st->callback) ircd::post([st(st)] + { + st->callback(st->eptr, st->val); + }); } inline void @@ -177,6 +189,10 @@ ircd::ctx::promise::set_exception(std::exception_ptr eptr) st->eptr = std::move(eptr); st->finished = true; st->cond.notify_all(); + if(st->callback) ircd::post([st(st)] + { + st->callback(st->eptr); + }); } template @@ -188,4 +204,8 @@ ircd::ctx::promise::set_exception(std::exception_ptr eptr) st->eptr = std::move(eptr); st->finished = true; st->cond.notify_all(); + if(st->callback) ircd::post([st(st)] + { + st->callback(st->eptr, st->val); + }); } diff --git a/include/ircd/ctx/shared_state.h b/include/ircd/ctx/shared_state.h index e9d422777..58d751cf8 100644 --- a/include/ircd/ctx/shared_state.h +++ b/include/ircd/ctx/shared_state.h @@ -36,6 +36,7 @@ struct ircd::ctx::shared_state using reference_type = T &; T val; + std::function callback; std::shared_ptr> share() const; std::shared_ptr> share(); @@ -48,6 +49,8 @@ struct ircd::ctx::shared_state { using value_type = void; + std::function callback; + std::shared_ptr> share() const; std::shared_ptr> share(); };