aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Juanli Shen <aspirinsjl@gmail.com>2018-03-13 17:17:05 -0700
committerGravatar GitHub <noreply@github.com>2018-03-13 17:17:05 -0700
commitf3b28b81cf5825ce41cbfdf1a926972227034d91 (patch)
tree5faa1f5e77da2df94a7c9460886e295bbc7a9d8b /src
parent431aea53db0f03578506dbd96615d65c360fa908 (diff)
parent7573f989add175f3d1aef5b2015a263b410d0f2a (diff)
Merge pull request #14681 from AspirinSJL/head
Fix call stack ref flake
Diffstat (limited to 'src')
-rw-r--r--src/core/lib/surface/call.cc34
1 files changed, 17 insertions, 17 deletions
diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc
index adb6ee5a06..c683cc02de 100644
--- a/src/core/lib/surface/call.cc
+++ b/src/core/lib/surface/call.cc
@@ -380,7 +380,7 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args,
bool immediately_cancel = false;
if (args->parent != nullptr) {
- child_call* cc = call->child =
+ call->child =
static_cast<child_call*>(gpr_arena_alloc(arena, sizeof(child_call)));
call->child->parent = args->parent;
@@ -388,10 +388,6 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args,
GPR_ASSERT(call->is_client);
GPR_ASSERT(!args->parent->is_client);
- parent_call* pc = get_or_create_parent_call(args->parent);
-
- gpr_mu_lock(&pc->child_list_mu);
-
if (args->propagation_mask & GRPC_PROPAGATE_DEADLINE) {
send_deadline = GPR_MIN(send_deadline, args->parent->send_deadline);
}
@@ -419,18 +415,6 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args,
immediately_cancel = true;
}
}
-
- if (pc->first_child == nullptr) {
- pc->first_child = call;
- cc->sibling_next = cc->sibling_prev = call;
- } else {
- cc->sibling_next = pc->first_child;
- cc->sibling_prev = pc->first_child->child->sibling_prev;
- cc->sibling_next->child->sibling_prev =
- cc->sibling_prev->child->sibling_next = call;
- }
-
- gpr_mu_unlock(&pc->child_list_mu);
}
call->send_deadline = send_deadline;
@@ -447,6 +431,22 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args,
&call->call_combiner};
add_init_error(&error, grpc_call_stack_init(channel_stack, 1, destroy_call,
call, &call_args));
+ // Publish this call to parent only after the call stack has been initialized.
+ if (args->parent != nullptr) {
+ child_call* cc = call->child;
+ parent_call* pc = get_or_create_parent_call(args->parent);
+ gpr_mu_lock(&pc->child_list_mu);
+ if (pc->first_child == nullptr) {
+ pc->first_child = call;
+ cc->sibling_next = cc->sibling_prev = call;
+ } else {
+ cc->sibling_next = pc->first_child;
+ cc->sibling_prev = pc->first_child->child->sibling_prev;
+ cc->sibling_next->child->sibling_prev =
+ cc->sibling_prev->child->sibling_next = call;
+ }
+ gpr_mu_unlock(&pc->child_list_mu);
+ }
if (error != GRPC_ERROR_NONE) {
cancel_with_error(call, STATUS_FROM_SURFACE, GRPC_ERROR_REF(error));
}