prevent spurious wake up and unstarted/already shutdown server

pull/7319/head
yang-g 9 years ago
parent e89dc6ceb6
commit 6ec11f2acd
  1. 1
      include/grpc++/server.h
  2. 7
      src/cpp/server/server.cc
  3. 7
      test/cpp/end2end/async_end2end_test.cc

@ -179,6 +179,7 @@ class Server GRPC_FINAL : public ServerInterface, private GrpcLibraryCodegen {
grpc::mutex mu_; grpc::mutex mu_;
bool started_; bool started_;
bool shutdown_; bool shutdown_;
bool shutdown_notified_;
// The number of threads which are running callbacks. // The number of threads which are running callbacks.
int num_running_cb_; int num_running_cb_;
grpc::condition_variable callback_cv_; grpc::condition_variable callback_cv_;

@ -281,6 +281,7 @@ Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned,
: max_message_size_(max_message_size), : max_message_size_(max_message_size),
started_(false), started_(false),
shutdown_(false), shutdown_(false),
shutdown_notified_(false),
num_running_cb_(0), num_running_cb_(0),
sync_methods_(new std::list<SyncRequest>), sync_methods_(new std::list<SyncRequest>),
has_generic_service_(false), has_generic_service_(false),
@ -462,13 +463,17 @@ void Server::ShutdownInternal(gpr_timespec deadline) {
while (num_running_cb_ != 0) { while (num_running_cb_ != 0) {
callback_cv_.wait(lock); callback_cv_.wait(lock);
} }
shutdown_notified_ = true;
shutdown_cv_.notify_all(); shutdown_cv_.notify_all();
} }
} }
void Server::Wait() { void Server::Wait() {
grpc::unique_lock<grpc::mutex> lock(mu_); 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) { void Server::PerformOpsOnCall(CallOpSetInterface* ops, Call* call) {

@ -363,6 +363,13 @@ TEST_P(AsyncEnd2endTest, WaitAndShutdownTest) {
delete wait_thread; 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 a simple RPC using the async version of Next
TEST_P(AsyncEnd2endTest, AsyncNextRpc) { TEST_P(AsyncEnd2endTest, AsyncNextRpc) {
ResetStub(); ResetStub();

Loading…
Cancel
Save