diff options
author | murgatroid99 <mlumish@google.com> | 2017-04-25 12:15:53 -0700 |
---|---|---|
committer | murgatroid99 <mlumish@google.com> | 2017-04-25 12:15:53 -0700 |
commit | 3049462b75ac557348243601896ed68ca8145522 (patch) | |
tree | 213389dd32b961b25f3833738201e857ce7ae2e3 /src/core/lib/iomgr/udp_server.c | |
parent | 627e2a5abd2e4146c85625e98083a95846ad57e8 (diff) | |
parent | 79759fea1abd09102d38af3e13a84b69e898124b (diff) |
Merge remote-tracking branch 'upstream/v1.3.x' into node_only_uv
Diffstat (limited to 'src/core/lib/iomgr/udp_server.c')
-rw-r--r-- | src/core/lib/iomgr/udp_server.c | 51 |
1 files changed, 42 insertions, 9 deletions
diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c index 60579e18ba..af70746064 100644 --- a/src/core/lib/iomgr/udp_server.c +++ b/src/core/lib/iomgr/udp_server.c @@ -79,14 +79,24 @@ struct grpc_udp_listener { grpc_resolved_address addr; grpc_closure read_closure; grpc_closure write_closure; + // To be called when corresponding QuicGrpcServer closes all active + // connections. + grpc_closure orphan_fd_closure; grpc_closure destroyed_closure; grpc_udp_server_read_cb read_cb; grpc_udp_server_write_cb write_cb; grpc_udp_server_orphan_cb orphan_cb; + // True if orphan_cb is trigered. + bool orphan_notified; struct grpc_udp_listener *next; }; +struct shutdown_fd_args { + grpc_fd *fd; + gpr_mu *server_mu; +}; + /* the overall server */ struct grpc_udp_server { gpr_mu mu; @@ -146,6 +156,19 @@ grpc_udp_server *grpc_udp_server_create(const grpc_channel_args *args) { return s; } +static void shutdown_fd(grpc_exec_ctx *exec_ctx, void *args, + grpc_error *error) { + struct shutdown_fd_args *shutdown_args = (struct shutdown_fd_args *)args; + gpr_mu_lock(shutdown_args->server_mu); + grpc_fd_shutdown(exec_ctx, shutdown_args->fd, GRPC_ERROR_REF(error)); + gpr_mu_unlock(shutdown_args->server_mu); + gpr_free(shutdown_args); +} + +static void dummy_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { + // No-op. +} + static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) { if (s->shutdown_complete != NULL) { grpc_closure_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE); @@ -195,12 +218,16 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) { grpc_closure_init(&sp->destroyed_closure, destroyed_port, s, grpc_schedule_on_exec_ctx); - - /* Call the orphan_cb to signal that the FD is about to be closed and - * should no longer be used. */ - GPR_ASSERT(sp->orphan_cb); - sp->orphan_cb(exec_ctx, sp->emfd, sp->server->user_data); - + if (!sp->orphan_notified) { + /* Call the orphan_cb to signal that the FD is about to be closed and + * should no longer be used. Because at this point, all listening ports + * have been shutdown already, no need to shutdown again.*/ + grpc_closure_init(&sp->orphan_fd_closure, dummy_cb, sp->emfd, + grpc_schedule_on_exec_ctx); + GPR_ASSERT(sp->orphan_cb); + sp->orphan_cb(exec_ctx, sp->emfd, &sp->orphan_fd_closure, + sp->server->user_data); + } grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL, "udp_listener_shutdown"); } @@ -225,9 +252,14 @@ void grpc_udp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_udp_server *s, if (s->active_ports) { for (sp = s->head; sp; sp = sp->next) { GPR_ASSERT(sp->orphan_cb); - sp->orphan_cb(exec_ctx, sp->emfd, sp->server->user_data); - grpc_fd_shutdown(exec_ctx, sp->emfd, GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Server destroyed")); + struct shutdown_fd_args *args = gpr_malloc(sizeof(*args)); + args->fd = sp->emfd; + args->server_mu = &s->mu; + grpc_closure_init(&sp->orphan_fd_closure, shutdown_fd, args, + grpc_schedule_on_exec_ctx); + sp->orphan_cb(exec_ctx, sp->emfd, &sp->orphan_fd_closure, + sp->server->user_data); + sp->orphan_notified = true; } gpr_mu_unlock(&s->mu); } else { @@ -391,6 +423,7 @@ static int add_socket_to_server(grpc_udp_server *s, int fd, sp->read_cb = read_cb; sp->write_cb = write_cb; sp->orphan_cb = orphan_cb; + sp->orphan_notified = false; GPR_ASSERT(sp->emfd); gpr_mu_unlock(&s->mu); gpr_free(name); |