diff options
author | 2015-06-02 08:15:33 -0700 | |
---|---|---|
committer | 2015-06-02 08:15:33 -0700 | |
commit | f93fd05a97081626dbd78c4553b6c2e78eeba920 (patch) | |
tree | d50c33113c3c09618527944f29738accb741225a /src/core/channel/client_channel.c | |
parent | 3a862e3b1047a081061d5ea207a7db3ec47a2e6d (diff) |
Fix use-after-free
Diffstat (limited to 'src/core/channel/client_channel.c')
-rw-r--r-- | src/core/channel/client_channel.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index ac34851504..1eda23b791 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -372,12 +372,24 @@ static void init_call_elem(grpc_call_element *elem, /* Destructor for call_data */ static void destroy_call_elem(grpc_call_element *elem) { call_data *calld = elem->call_data; + channel_data *chand = elem->channel_data; /* if the call got activated, we need to destroy the child stack also, and remove it from the in-flight requests tracked by the child_entry we picked */ - if (calld->state == CALL_ACTIVE) { - grpc_child_call_destroy(calld->s.active.child_call); + gpr_mu_lock(&chand->mu); + switch (calld->state) { + case CALL_ACTIVE: + gpr_mu_unlock(&chand->mu); + grpc_child_call_destroy(calld->s.active.child_call); + break; + case CALL_WAITING: + remove_waiting_child(chand, calld); + gpr_mu_unlock(&chand->mu); + break; + default: + gpr_mu_unlock(&chand->mu); + break; } GPR_ASSERT(calld->state != CALL_WAITING); } |