]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: http client drops mutex before suspending coroutine 29553/head
authorCasey Bodley <cbodley@redhat.com>
Thu, 8 Aug 2019 14:06:17 +0000 (10:06 -0400)
committerCasey Bodley <cbodley@redhat.com>
Thu, 8 Aug 2019 14:06:40 +0000 (10:06 -0400)
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>
src/rgw/rgw_http_client.cc

index 7c0c77e341cc4d3dc570eedbb57edae1a7be51bb..fccc52e6e62b358fb5bf1be5cd65ce929ab0dd44 100644 (file)
@@ -60,12 +60,14 @@ struct rgw_http_req_data : public RefCountedObject {
   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;
     }
@@ -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;
   }