From ced73bde96f64b40d0798cb915cc59ae1c240f26 Mon Sep 17 00:00:00 2001
From: Vijay Pai <vpai@google.com>
Date: Wed, 17 Jun 2015 10:23:28 -0700
Subject: [PATCH] Split cq creation from request initiation so that cq creation
 can be removed from C++ lock.

---
 src/cpp/server/server.cc | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc
index dbd88c5b8c..024537c34a 100644
--- a/src/cpp/server/server.cc
+++ b/src/cpp/server/server.cc
@@ -71,7 +71,8 @@ class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag {
                                  RpcMethod::SERVER_STREAMING),
         has_response_payload_(method->method_type() == RpcMethod::NORMAL_RPC ||
                               method->method_type() ==
-                                  RpcMethod::CLIENT_STREAMING) {
+                              RpcMethod::CLIENT_STREAMING),
+        cq_(nullptr) {
     grpc_metadata_array_init(&request_metadata_);
   }
 
@@ -90,10 +91,18 @@ class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag {
     return mrd;
   }
 
+  void SetupRequest() {
+    cq_ = grpc_completion_queue_create();
+  }
+
+  void TeardownRequest() {
+    grpc_completion_queue_destroy(cq_);
+    cq_ = nullptr;
+  }
+
   void Request(grpc_server* server, grpc_completion_queue* notify_cq) {
-    GPR_ASSERT(!in_flight_);
+    GPR_ASSERT(cq_ && !in_flight_);
     in_flight_ = true;
-    cq_ = grpc_completion_queue_create();
     GPR_ASSERT(GRPC_CALL_OK ==
                grpc_server_request_registered_call(
                    server, tag_, &call_, &deadline_, &request_metadata_,
@@ -288,6 +297,7 @@ bool Server::Start() {
   // Start processing rpcs.
   if (!sync_methods_->empty()) {
     for (auto m = sync_methods_->begin(); m != sync_methods_->end(); m++) {
+      m->SetupRequest();
       m->Request(server_, cq_.cq());
     }
 
@@ -472,9 +482,13 @@ void Server::RunRpc() {
     if (ok) {
       SyncRequest::CallData cd(this, mrd);
       {
+        mrd->SetupRequest();
         grpc::unique_lock<grpc::mutex> lock(mu_);
         if (!shutdown_) {
           mrd->Request(server_, cq_.cq());
+        } else {
+          // destroy the structure that was created
+          mrd->TeardownRequest();
         }
       }
       cd.Run();
-- 
GitLab