aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/cpp/server/server_cc.cc
diff options
context:
space:
mode:
authorGravatar Yang Gao <yangg@google.com>2018-11-08 15:57:48 -0800
committerGravatar GitHub <noreply@github.com>2018-11-08 15:57:48 -0800
commited6ea2cf7d7edc29bef7f3e48dcf058fe1090490 (patch)
tree10f10555a805ddeafa88ed6983ad5d84944f0a10 /src/cpp/server/server_cc.cc
parent6eb888bc6c764021d0ab97fa1e1ccdcc461c3614 (diff)
parentbc3d6d21b767cf360f98f540111e434234b5eda2 (diff)
Merge pull request #17151 from arjunroy/grpc_memleak_fix
Fixed intermittent CPP sync server shutdown leak.
Diffstat (limited to 'src/cpp/server/server_cc.cc')
-rw-r--r--src/cpp/server/server_cc.cc24
1 files changed, 23 insertions, 1 deletions
diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc
index 6e1adacc87..7a98bce507 100644
--- a/src/cpp/server/server_cc.cc
+++ b/src/cpp/server/server_cc.cc
@@ -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();
+ }
}
}