mirror of
https://github.com/matrix-construct/construct
synced 2024-11-17 23:40:57 +01:00
ircd::ctx: Fixes for the thread-unsafety of asio::steady_timer.
This commit is contained in:
parent
c604b391be
commit
33b2cd8f70
1 changed files with 14 additions and 7 deletions
21
ircd/ctx.cc
21
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<void ()> &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<bool> 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<void ()> &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);
|
||||
|
|
Loading…
Reference in a new issue