aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib/surface
diff options
context:
space:
mode:
authorGravatar Mark D. Roth <roth@google.com>2017-09-05 13:46:41 -0700
committerGravatar Mark D. Roth <roth@google.com>2017-09-05 13:46:41 -0700
commit180c6b184bcbf2315da8d45a8dd015f9f908d429 (patch)
treef198efbb37b0c44ee438c7e3864e0e046b377e70 /src/core/lib/surface
parentb2b9a0ff7eacc84335b800e31b13a7607acf614b (diff)
Reset cancellation closure when unreffing the call to avoid race conditions.
Diffstat (limited to 'src/core/lib/surface')
-rw-r--r--src/core/lib/surface/call.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c
index 03eaaf99ac..3aa20ffcd7 100644
--- a/src/core/lib/surface/call.c
+++ b/src/core/lib/surface/call.c
@@ -598,6 +598,12 @@ void grpc_call_unref(grpc_call *c) {
if (cancel) {
cancel_with_error(&exec_ctx, c, STATUS_FROM_API_OVERRIDE,
GRPC_ERROR_CANCELLED);
+ } else {
+ // Unset the call combiner cancellation closure. This has the
+ // effect of scheduling the previously set cancellation closure, if
+ // any, so that it can release any internal references it may be
+ // holding to the call stack.
+ grpc_call_combiner_set_notify_on_cancel(&exec_ctx, &c->call_combiner, NULL);
}
GRPC_CALL_INTERNAL_UNREF(&exec_ctx, c, "destroy");
grpc_exec_ctx_finish(&exec_ctx);