the lock can't be held over async_wait(), because the call to finish()
won't be able to reacquire the lock in order to fire the completion.
coroutines may also resume on a different thread, and you can't unlock a
mutex that was locked on another thread
Reported-by: Yuval Lifshitz <yuvalif@yahoo.com>
Signed-off-by: Casey Bodley <cbodley@redhat.com>
auto async_wait(ExecutionContext& ctx, CompletionToken&& token) {
boost::asio::async_completion<CompletionToken, Signature> init(token);
auto& handler = init.completion_handler;
- completion = Completion::create(ctx.get_executor(), std::move(handler));
+ {
+ std::unique_lock l{lock};
+ completion = Completion::create(ctx.get_executor(), std::move(handler));
+ }
return init.result.get();
}
int wait(optional_yield y) {
- std::unique_lock l{lock};
if (done) {
return ret;
}
dout(20) << "WARNING: blocking http request" << dendl;
}
#endif
+ std::unique_lock l{lock};
cond.wait(l);
return ret;
}