From 9275d4067cfd9233edf2ae9a0fe1255c8c730f19 Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 11 Jul 2016 16:51:39 -0700 Subject: Shutdown the listeners early when destroying the tcp_server --- src/core/lib/iomgr/tcp_server.h | 4 ++++ src/core/lib/iomgr/tcp_server_posix.c | 13 +++++++++++++ src/core/lib/iomgr/tcp_server_windows.c | 3 +++ 3 files changed, 20 insertions(+) (limited to 'src/core/lib') diff --git a/src/core/lib/iomgr/tcp_server.h b/src/core/lib/iomgr/tcp_server.h index 875a6ca14a..5a25d39a0c 100644 --- a/src/core/lib/iomgr/tcp_server.h +++ b/src/core/lib/iomgr/tcp_server.h @@ -105,4 +105,8 @@ void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s, a call (exec_ctx!=NULL) to shutdown_complete. */ void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s); +/* Shutdown the fds of listeners. */ +void grpc_tcp_server_shutdown_listeners(grpc_exec_ctx *exec_ctx, + grpc_tcp_server *s); + #endif /* GRPC_CORE_LIB_IOMGR_TCP_SERVER_H */ diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c index d3803c3bd0..7b713723ce 100644 --- a/src/core/lib/iomgr/tcp_server_posix.c +++ b/src/core/lib/iomgr/tcp_server_posix.c @@ -740,4 +740,17 @@ void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { } } +void grpc_tcp_server_shutdown_listeners(grpc_exec_ctx *exec_ctx, + grpc_tcp_server *s) { + gpr_mu_lock(&s->mu); + /* shutdown all fd's */ + if (s->active_ports) { + grpc_tcp_listener *sp; + for (sp = s->head; sp; sp = sp->next) { + grpc_fd_shutdown(exec_ctx, sp->emfd); + } + } + gpr_mu_unlock(&s->mu); +} + #endif diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c index 7b0966704c..1b125e7005 100644 --- a/src/core/lib/iomgr/tcp_server_windows.c +++ b/src/core/lib/iomgr/tcp_server_windows.c @@ -540,4 +540,7 @@ void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s, gpr_mu_unlock(&s->mu); } +void grpc_tcp_server_shutdown_listeners(grpc_exec_ctx *exec_ctx, + grpc_tcp_server *s) {} + #endif /* GPR_WINSOCK_SOCKET */ -- cgit v1.2.3 From fca59fb2aa4a0be093d12162c763b8563ada4087 Mon Sep 17 00:00:00 2001 From: Sanjay Ghemawat Date: Thu, 21 Jul 2016 09:32:06 -0700 Subject: Add gpr_slice_new_with_user_data. gpr_slice_new_with_user_data is like gpr_slice_new, but allows the caller to specify a distinct pointer to pass to the destroy function. This is useful when the data is part of a larger data structure that should be destroyed when the data is no longer needed. --- include/grpc/impl/codegen/slice.h | 8 ++++++++ src/core/lib/support/slice.c | 11 +++++++++-- test/core/support/slice_test.c | 22 ++++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) (limited to 'src/core/lib') diff --git a/include/grpc/impl/codegen/slice.h b/include/grpc/impl/codegen/slice.h index c684b7587d..dfc0a774fc 100644 --- a/include/grpc/impl/codegen/slice.h +++ b/include/grpc/impl/codegen/slice.h @@ -120,6 +120,14 @@ GPRAPI void gpr_slice_unref(gpr_slice s); passed in at destruction. */ GPRAPI gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *)); +/* Equivalent to gpr_slice_new, but with a separate pointer that is + passed to the destroy function. This function can be useful when + the data is part of a larger structure that must be destroyed when + the data is no longer needed. */ +GPRAPI gpr_slice gpr_slice_new_with_user_data(void *p, size_t len, + void (*destroy)(void *), + void *user_data); + /* Equivalent to gpr_slice_new, but with a two argument destroy function that also takes the slice length. */ GPRAPI gpr_slice gpr_slice_new_with_len(void *p, size_t len, diff --git a/src/core/lib/support/slice.c b/src/core/lib/support/slice.c index b9a7c77bda..8a2c0a9086 100644 --- a/src/core/lib/support/slice.c +++ b/src/core/lib/support/slice.c @@ -94,14 +94,16 @@ static void new_slice_unref(void *p) { } } -gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *)) { +gpr_slice gpr_slice_new_with_user_data(void *p, size_t len, + void (*destroy)(void *), + void *user_data) { gpr_slice slice; new_slice_refcount *rc = gpr_malloc(sizeof(new_slice_refcount)); gpr_ref_init(&rc->refs, 1); rc->rc.ref = new_slice_ref; rc->rc.unref = new_slice_unref; rc->user_destroy = destroy; - rc->user_data = p; + rc->user_data = user_data; slice.refcount = &rc->rc; slice.data.refcounted.bytes = p; @@ -109,6 +111,11 @@ gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *)) { return slice; } +gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *)) { + /* Pass "p" to *destroy when the slice is no longer needed. */ + return gpr_slice_new_with_user_data(p, len, destroy, p); +} + /* gpr_slice_new_with_len support structures - we create a refcount object extended with the user provided data pointer & destroy function */ typedef struct new_with_len_slice_refcount { diff --git a/test/core/support/slice_test.c b/test/core/support/slice_test.c index 0da483a321..06c364b368 100644 --- a/test/core/support/slice_test.c +++ b/test/core/support/slice_test.c @@ -85,6 +85,27 @@ static void test_slice_new_returns_something_sensible(void) { gpr_slice_unref(slice); } +/* destroy function that sets a mark to indicate it was called. */ +static void set_mark(void *p) { *((int *)p) = 1; } + +static void test_slice_new_with_user_data(void) { + int marker = 0; + uint8_t buf[2]; + gpr_slice slice; + + buf[0] = 0; + buf[1] = 1; + slice = gpr_slice_new_with_user_data(buf, 2, set_mark, &marker); + GPR_ASSERT(marker == 0); + GPR_ASSERT(GPR_SLICE_LENGTH(slice) == 2); + GPR_ASSERT(GPR_SLICE_START_PTR(slice)[0] == 0); + GPR_ASSERT(GPR_SLICE_START_PTR(slice)[1] == 1); + + /* unref should cause destroy function to run. */ + gpr_slice_unref(slice); + GPR_ASSERT(marker == 1); +} + static int do_nothing_with_len_1_calls = 0; static void do_nothing_with_len_1(void *ignored, size_t len) { @@ -232,6 +253,7 @@ int main(int argc, char **argv) { grpc_test_init(argc, argv); test_slice_malloc_returns_something_sensible(); test_slice_new_returns_something_sensible(); + test_slice_new_with_user_data(); test_slice_new_with_len_returns_something_sensible(); for (length = 0; length < 128; length++) { test_slice_sub_works(length); -- cgit v1.2.3