diff --git a/include/ircd/ctx/promise.h b/include/ircd/ctx/promise.h index 8b91d16d7..b1e0c6d8b 100644 --- a/include/ircd/ctx/promise.h +++ b/include/ircd/ctx/promise.h @@ -58,9 +58,7 @@ class ircd::ctx::promise promise(); promise(promise &&o) noexcept = default; - promise(const promise &) = delete; - promise &operator=(promise &&o) noexcept = default; - promise &operator=(const promise &) = delete; + promise(const promise &); ~promise() noexcept; }; @@ -85,9 +83,7 @@ class ircd::ctx::promise promise(); promise(promise &&o) noexcept = default; - promise(const promise &) = delete; - promise &operator=(promise &&) noexcept = default; - promise &operator=(const promise &) = delete; + promise(const promise &); ~promise() noexcept; }; @@ -95,28 +91,52 @@ inline ircd::ctx::promise::promise() :st{std::make_shared>()} { + ++st->promise_refcnt; + assert(st->promise_refcnt == 1); } template ircd::ctx::promise::promise() :st{std::make_shared>()} { + ++st->promise_refcnt; + assert(st->promise_refcnt == 1); +} + +inline +ircd::ctx::promise::promise(const promise &o) +:st{o.st} +{ + ++st->promise_refcnt; + assert(st->promise_refcnt > 1); +} + +template +ircd::ctx::promise::promise(const promise &o) +:st{o.st} +{ + ++st->promise_refcnt; + assert(st->promise_refcnt > 1); } inline ircd::ctx::promise::~promise() noexcept { - if(valid() && !st->finished && !st.unique()) - set_exception(std::make_exception_ptr(broken_promise())); + if(valid()) + if(!--st->promise_refcnt) + if(!st->finished && !st.unique()) + set_exception(std::make_exception_ptr(broken_promise())); } template ircd::ctx::promise::~promise() noexcept { - if(valid() && !st->finished && !st.unique()) - set_exception(std::make_exception_ptr(broken_promise())); + if(valid()) + if(!--st->promise_refcnt) + if(!st->finished && !st.unique()) + set_exception(std::make_exception_ptr(broken_promise())); } inline void diff --git a/include/ircd/ctx/shared_state.h b/include/ircd/ctx/shared_state.h index 818d2840f..d79247390 100644 --- a/include/ircd/ctx/shared_state.h +++ b/include/ircd/ctx/shared_state.h @@ -33,7 +33,8 @@ struct ircd::ctx::shared_state_base { dock cond; std::exception_ptr eptr; - bool finished = false; + uint promise_refcnt {0}; + bool finished {false}; void reset(); };