From 0ede545127f28cee6e9c0882e27b79f939979755 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Sat, 23 Apr 2016 12:21:45 -0700 Subject: [PATCH] Fix memory leak on disconnection --- src/core/ext/client_config/client_channel.c | 12 ++++++++---- src/core/lib/iomgr/closure.c | 6 ++++++ src/core/lib/iomgr/closure.h | 3 +++ src/core/lib/iomgr/exec_ctx.h | 2 ++ 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/core/ext/client_config/client_channel.c b/src/core/ext/client_config/client_channel.c index 93d54fdcfeb..06365df587b 100644 --- a/src/core/ext/client_config/client_channel.c +++ b/src/core/ext/client_config/client_channel.c @@ -205,7 +205,11 @@ static void cc_on_config_changed(grpc_exec_ctx *exec_ctx, void *arg, gpr_mu_lock(&chand->mu_config); old_lb_policy = chand->lb_policy; chand->lb_policy = lb_policy; - if (lb_policy != NULL || chand->resolver == NULL /* disconnected */) { + if (lb_policy != NULL) { + grpc_exec_ctx_enqueue_list(exec_ctx, &chand->waiting_for_config_closures, + NULL); + } else if (chand->resolver == NULL /* disconnected */) { + grpc_closure_list_fail_all(&chand->waiting_for_config_closures); grpc_exec_ctx_enqueue_list(exec_ctx, &chand->waiting_for_config_closures, NULL); } @@ -321,10 +325,10 @@ static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *arg, static void continue_picking(grpc_exec_ctx *exec_ctx, void *arg, bool success) { continue_picking_args *cpa = arg; - if (!success) { - grpc_exec_ctx_enqueue(exec_ctx, cpa->on_ready, false, NULL); - } else if (cpa->connected_subchannel == NULL) { + if (cpa->connected_subchannel == NULL) { /* cancelled, do nothing */ + } else if (!success) { + grpc_exec_ctx_enqueue(exec_ctx, cpa->on_ready, false, NULL); } else if (cc_pick_subchannel(exec_ctx, cpa->elem, cpa->initial_metadata, cpa->initial_metadata_flags, cpa->connected_subchannel, cpa->on_ready)) { diff --git a/src/core/lib/iomgr/closure.c b/src/core/lib/iomgr/closure.c index d6f073fc9db..27793c32e42 100644 --- a/src/core/lib/iomgr/closure.c +++ b/src/core/lib/iomgr/closure.c @@ -54,6 +54,12 @@ void grpc_closure_list_add(grpc_closure_list *closure_list, closure_list->tail = closure; } +void grpc_closure_list_fail_all(grpc_closure_list *list) { + for (grpc_closure *c = list->head; c != NULL; c = grpc_closure_next(c)) { + c->final_data &= ~(uintptr_t)1; + } +} + bool grpc_closure_list_empty(grpc_closure_list closure_list) { return closure_list.head == NULL; } diff --git a/src/core/lib/iomgr/closure.h b/src/core/lib/iomgr/closure.h index 8652b53a8b8..fdc2daed9d4 100644 --- a/src/core/lib/iomgr/closure.h +++ b/src/core/lib/iomgr/closure.h @@ -86,6 +86,9 @@ grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg); void grpc_closure_list_add(grpc_closure_list *list, grpc_closure *closure, bool success); +/** force all success bits in \a list to false */ +void grpc_closure_list_fail_all(grpc_closure_list *list); + /** append all closures from \a src to \a dst and empty \a src. */ void grpc_closure_list_move(grpc_closure_list *src, grpc_closure_list *dst); diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index e09ef024008..976cc403475 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -92,6 +92,8 @@ void grpc_exec_ctx_enqueue_list(grpc_exec_ctx *exec_ctx, grpc_closure_list *list, grpc_workqueue *offload_target_or_null); +void grpc_exec_ctx_global_init(void); + void grpc_exec_ctx_global_init(void); void grpc_exec_ctx_global_shutdown(void);