From 57887f6a364e06ade69fdf2277122c496ab8a134 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Thu, 8 Aug 2019 10:06:17 -0400 Subject: [PATCH] rgw: http client drops mutex before suspending coroutine 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 Signed-off-by: Casey Bodley --- src/rgw/rgw_http_client.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/rgw/rgw_http_client.cc b/src/rgw/rgw_http_client.cc index 7c0c77e341c..fccc52e6e62 100644 --- a/src/rgw/rgw_http_client.cc +++ b/src/rgw/rgw_http_client.cc @@ -60,12 +60,14 @@ struct rgw_http_req_data : public RefCountedObject { auto async_wait(ExecutionContext& ctx, CompletionToken&& token) { boost::asio::async_completion 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; } @@ -82,6 +84,7 @@ struct rgw_http_req_data : public RefCountedObject { dout(20) << "WARNING: blocking http request" << dendl; } #endif + std::unique_lock l{lock}; cond.wait(l); return ret; } -- 2.47.3