aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib/iomgr/udp_server.c
diff options
context:
space:
mode:
authorGravatar murgatroid99 <mlumish@google.com>2017-04-25 12:15:53 -0700
committerGravatar murgatroid99 <mlumish@google.com>2017-04-25 12:15:53 -0700
commit3049462b75ac557348243601896ed68ca8145522 (patch)
tree213389dd32b961b25f3833738201e857ce7ae2e3 /src/core/lib/iomgr/udp_server.c
parent627e2a5abd2e4146c85625e98083a95846ad57e8 (diff)
parent79759fea1abd09102d38af3e13a84b69e898124b (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.c51
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);