aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Juanli Shen <juanlishen@google.com>2018-03-12 18:06:13 -0700
committerGravatar Juanli Shen <juanlishen@google.com>2018-03-12 18:06:13 -0700
commit7573f989add175f3d1aef5b2015a263b410d0f2a (patch)
tree850f176a56c167db4c031ce2e8a15bc7f656b423 /src
parente5335b49ec35659c591bfbfb34825d181af5f4c3 (diff)
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 c4844da318..deb2b9f45f 100644
--- a/src/core/lib/surface/call.cc
+++ b/src/core/lib/surface/call.cc
@@ -379,7 +379,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;
@@ -387,10 +387,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);
}
@@ -418,18 +414,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;
@@ -446,6 +430,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));
}