diff options
author | Mark D. Roth <roth@google.com> | 2016-07-20 10:08:48 -0700 |
---|---|---|
committer | Mark D. Roth <roth@google.com> | 2016-07-20 10:08:48 -0700 |
commit | 0b84add2818028cfc881358c6f81bb4a5ac3d135 (patch) | |
tree | 288a9a3d9624c3ec5ac86ea0766e0f4f8f3cb016 /src | |
parent | 5682a52cee47d6bbdd71bf1426cd603b306cc2b7 (diff) |
Avoid allocating memory for each individual handshaker. Also fix memory leak.
Diffstat (limited to 'src')
-rw-r--r-- | src/core/lib/channel/handshaker.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c index 9db04440ee..ed8eb4a7f8 100644 --- a/src/core/lib/channel/handshaker.c +++ b/src/core/lib/channel/handshaker.c @@ -100,10 +100,24 @@ grpc_handshake_manager* grpc_handshake_manager_create() { return mgr; } +static bool is_power_of_2(size_t n) { + return (n & (n - 1)) == 0; +} + void grpc_handshake_manager_add(grpc_handshaker* handshaker, grpc_handshake_manager* mgr) { - mgr->handshakers = gpr_realloc(mgr->handshakers, - (mgr->count + 1) * sizeof(grpc_handshaker*)); + // To avoid allocating memory for each handshaker we add, we double + // the number of elements every time we need more. + size_t realloc_count = 0; + if (mgr->count == 0) { + realloc_count = 2; + } else if (mgr->count >= 2 && is_power_of_2(mgr->count)) { + realloc_count = mgr->count * 2; + } + if (realloc_count > 0) { + mgr->handshakers = gpr_realloc(mgr->handshakers, + realloc_count * sizeof(grpc_handshaker*)); + } mgr->handshakers[mgr->count++] = handshaker; } @@ -112,6 +126,7 @@ void grpc_handshake_manager_destroy(grpc_exec_ctx* exec_ctx, for (size_t i = 0; i < mgr->count; ++i) { grpc_handshaker_destroy(exec_ctx, mgr->handshakers[i]); } + gpr_free(mgr->handshakers); gpr_free(mgr); } |