diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c index 5daf406c99d6677fe76a86b67735f8f132e3cb01..1439dfcd6edb0b6b773a19344ba0540a3d84ab08 100644 --- a/src/core/iomgr/tcp_server_posix.c +++ b/src/core/iomgr/tcp_server_posix.c @@ -67,7 +67,6 @@ #include <grpc/support/sync.h> #include <grpc/support/time.h> -#define INIT_PORT_CAP 2 #define MIN_SAFE_ACCEPT_QUEUE_SIZE 100 static gpr_once s_init_max_accept_queue_size; @@ -89,8 +88,12 @@ struct grpc_tcp_listener { grpc_closure destroyed_closure; gpr_refcount refs; struct grpc_tcp_listener *next; - struct grpc_tcp_listener *dual_stack_second_port; - int is_dual_stack_second_port; + /* When we add a listener, more than one can be created, mainly because of + IPv6. A sibling will still be in the normal list, but will be flagged + as such. Any action, such as ref or unref, will affect all of the + siblings in the list. */ + struct grpc_tcp_listener *sibling; + int is_sibling; }; static void unlink_if_unix_domain_socket(const struct sockaddr_un *un) { @@ -394,8 +397,8 @@ static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, int fd, memcpy(sp->addr.untyped, addr, addr_len); sp->addr_len = addr_len; sp->port = port; - sp->is_dual_stack_second_port = 0; - sp->dual_stack_second_port = NULL; + sp->is_sibling = 0; + sp->sibling = NULL; gpr_ref_init(&sp->refs, 1); GPR_ASSERT(sp->emfd); gpr_mu_unlock(&s->mu); @@ -486,8 +489,8 @@ grpc_tcp_listener *grpc_tcp_server_add_port(grpc_tcp_server *s, addr_len = sizeof(addr4_copy); } sp = add_socket_to_server(s, fd, addr, addr_len); - sp->dual_stack_second_port = sp2; - if (sp2) sp2->is_dual_stack_second_port = 1; + sp->sibling = sp2; + if (sp2) sp2->is_sibling = 1; done: gpr_free(allocated_addr); @@ -543,9 +546,14 @@ void grpc_tcp_listener_ref(grpc_tcp_listener *listener) { void grpc_tcp_listener_unref(grpc_tcp_listener *listener) { grpc_tcp_listener *sp = listener; - if (sp->is_dual_stack_second_port) return; + if (sp->is_sibling) return; if (gpr_unref(&sp->refs)) { - if (sp->dual_stack_second_port) gpr_free(sp->dual_stack_second_port); + grpc_tcp_listener *sibling = sp->sibling; + while (sibling) { + sp = sibling; + sibling = sp->sibling; + gpr_free(sp); + } gpr_free(listener); } }