From 807387641f8a8acceb3a8e58adabf3080afb871d Mon Sep 17 00:00:00 2001
From: yang-g <yangg@google.com>
Date: Thu, 14 Jul 2016 14:53:35 -0700
Subject: [PATCH] prevent spurious wake up and unstarted/already shutdown
 server

---
 include/grpc++/server.h                | 1 +
 src/cpp/server/server.cc               | 7 ++++++-
 test/cpp/end2end/async_end2end_test.cc | 7 +++++++
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index 9a2f8f11c4..6876961e21 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -179,6 +179,7 @@ class Server GRPC_FINAL : public ServerInterface, private GrpcLibraryCodegen {
   grpc::mutex mu_;
   bool started_;
   bool shutdown_;
+  bool shutdown_notified_;
   // The number of threads which are running callbacks.
   int num_running_cb_;
   grpc::condition_variable callback_cv_;
diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc
index 374c9cbc04..af04fd4ca6 100644
--- a/src/cpp/server/server.cc
+++ b/src/cpp/server/server.cc
@@ -281,6 +281,7 @@ Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned,
     : max_message_size_(max_message_size),
       started_(false),
       shutdown_(false),
+      shutdown_notified_(false),
       num_running_cb_(0),
       sync_methods_(new std::list<SyncRequest>),
       has_generic_service_(false),
@@ -462,13 +463,17 @@ void Server::ShutdownInternal(gpr_timespec deadline) {
     while (num_running_cb_ != 0) {
       callback_cv_.wait(lock);
     }
+
+    shutdown_notified_ = true;
     shutdown_cv_.notify_all();
   }
 }
 
 void Server::Wait() {
   grpc::unique_lock<grpc::mutex> lock(mu_);
-  shutdown_cv_.wait(lock);
+  while (started_ && !shutdown_notified_) {
+    shutdown_cv_.wait(lock);
+  }
 }
 
 void Server::PerformOpsOnCall(CallOpSetInterface* ops, Call* call) {
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index 01ba8962d7..4a8936d281 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -363,6 +363,13 @@ TEST_P(AsyncEnd2endTest, WaitAndShutdownTest) {
   delete wait_thread;
 }
 
+TEST_P(AsyncEnd2endTest, ShutdownThenWait) {
+  ResetStub();
+  SendRpc(1);
+  server_->Shutdown();
+  server_->Wait();
+}
+
 // Test a simple RPC using the async version of Next
 TEST_P(AsyncEnd2endTest, AsyncNextRpc) {
   ResetStub();
-- 
GitLab