From 33b2cd8f70281b27147560b927d2f762650d5c38 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Tue, 28 Mar 2017 22:44:01 -0700 Subject: [PATCH] ircd::ctx: Fixes for the thread-unsafety of asio::steady_timer. --- ircd/ctx.cc | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/ircd/ctx.cc b/ircd/ctx.cc index 00fa8ee3c..1912750b4 100644 --- a/ircd/ctx.cc +++ b/ircd/ctx.cc @@ -39,6 +39,7 @@ struct ctx uint64_t id; // Unique runtime ID const char *name; // User given name (optional) context::flags flags; // User given flags + boost::asio::io_service::strand strand; // mutex/serializer boost::asio::steady_timer alarm; // acting semaphore (64B) boost::asio::yield_context *yc; // boost interface uintptr_t stack_base; // assigned when spawned @@ -85,6 +86,7 @@ ircd::ctx::ctx::ctx(const char *const &name, :id{++id_ctr} ,name{name} ,flags{flags} +,strand{*ios} ,alarm{*ios} ,yc{nullptr} ,stack_base{0} @@ -383,7 +385,7 @@ ircd::ctx::context::context(const char *const &name, boost::coroutines::stack_unwind }; - boost::asio::spawn(*ios, std::move(bound), attrs); + boost::asio::spawn(c->strand, std::move(bound), attrs); }); // The current context must be reasserted if spawn returns here @@ -762,10 +764,16 @@ noexcept void ircd::ctx::ole::offload(const std::function &func) { + bool done(false); + auto *const context(current); + const auto notifier([&context, &done] + { + done = true; + notify(*context); + }); + std::exception_ptr eptr; - auto &context(cur()); - std::atomic done{false}; - auto closure([&func, &eptr, &context, &done] + auto closure([&func, &eptr, &context, ¬ifier] () noexcept { try @@ -777,15 +785,14 @@ ircd::ctx::ole::offload(const std::function &func) eptr = std::current_exception(); } - done.store(true, std::memory_order_release); - notify(context); + context->strand.post(notifier); }); push(std::move(closure)); do { wait(); } - while(!done.load(std::memory_order_consume)); + while(!done); if(eptr) std::rethrow_exception(eptr);