aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/channel/client_channel.c
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2015-02-05 10:10:15 -0800
committerGravatar Craig Tiller <ctiller@google.com>2015-02-05 10:10:15 -0800
commitda66937e34a18e3d97d03faa7035664610275379 (patch)
treeea272a74580f73613461907f78c8bb2c97e088d7 /src/core/channel/client_channel.c
parent051a55c3b752aafbf2d3e20fb5471c4e2ef4b2db (diff)
Force a round trip on disconnect before closing a channel
Prevents a use-after-free
Diffstat (limited to 'src/core/channel/client_channel.c')
-rw-r--r--src/core/channel/client_channel.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c
index bcb024f2ac..507b91b8a6 100644
--- a/src/core/channel/client_channel.c
+++ b/src/core/channel/client_channel.c
@@ -298,6 +298,7 @@ static void channel_op(grpc_channel_element *elem,
grpc_channel_element *from_elem, grpc_channel_op *op) {
channel_data *chand = elem->channel_data;
grpc_child_channel *child_channel;
+ grpc_channel_op rop;
GPR_ASSERT(elem->filter == &grpc_client_channel_filter);
switch (op->type) {
@@ -323,6 +324,10 @@ static void channel_op(grpc_channel_element *elem,
if (child_channel) {
grpc_child_channel_destroy(child_channel, 1);
}
+ /* fake a transport closed to satisfy the refcounting in client */
+ rop.type = GRPC_TRANSPORT_CLOSED;
+ rop.dir = GRPC_CALL_UP;
+ grpc_channel_next_op(elem, &rop);
break;
case GRPC_TRANSPORT_GOAWAY:
/* receiving goaway: if it's from our active child, drop the active child;