|  | @@ -202,9 +202,21 @@ class Server::SyncRequest final : public internal::CompletionQueueTag {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  void PostShutdownCleanup() {
 | 
	
		
			
				|  |  | +    if (call_) {
 | 
	
		
			
				|  |  | +      grpc_call_unref(call_);
 | 
	
		
			
				|  |  | +      call_ = nullptr;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if (cq_) {
 | 
	
		
			
				|  |  | +      grpc_completion_queue_destroy(cq_);
 | 
	
		
			
				|  |  | +      cq_ = nullptr;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    bool FinalizeResult(void** tag, bool* status) override {
 | 
	
		
			
				|  |  |      if (!*status) {
 | 
	
		
			
				|  |  |        grpc_completion_queue_destroy(cq_);
 | 
	
		
			
				|  |  | +      cq_ = nullptr;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      if (call_details_) {
 | 
	
		
			
				|  |  |        deadline_ = call_details_->deadline;
 | 
	
	
		
			
				|  | @@ -589,7 +601,17 @@ class Server::SyncRequestThreadManager : public ThreadManager {
 | 
	
		
			
				|  |  |      void* tag;
 | 
	
		
			
				|  |  |      bool ok;
 | 
	
		
			
				|  |  |      while (server_cq_->Next(&tag, &ok)) {
 | 
	
		
			
				|  |  | -      // Do nothing
 | 
	
		
			
				|  |  | +      if (ok) {
 | 
	
		
			
				|  |  | +        // If a request was pulled off the queue, it means that the thread
 | 
	
		
			
				|  |  | +        // handling the request added it to the completion queue after shutdown
 | 
	
		
			
				|  |  | +        // was called - because the thread had already started and checked the
 | 
	
		
			
				|  |  | +        // shutdown flag before shutdown was called. In this case, we simply
 | 
	
		
			
				|  |  | +        // clean it up here, *after* calling wait on all the worker threads, at
 | 
	
		
			
				|  |  | +        // which point we are certain no in-flight requests will add more to the
 | 
	
		
			
				|  |  | +        // queue. This fixes an intermittent memory leak on shutdown.
 | 
	
		
			
				|  |  | +        SyncRequest* sync_req = static_cast<SyncRequest*>(tag);
 | 
	
		
			
				|  |  | +        sync_req->PostShutdownCleanup();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 |