diff options
author | Mark D. Roth <roth@google.com> | 2016-08-11 08:52:02 -0700 |
---|---|---|
committer | Mark D. Roth <roth@google.com> | 2016-08-11 08:52:02 -0700 |
commit | fddb3d3451940c35990da8191a4345723a90da2d (patch) | |
tree | 48e0630c57e9cdf20577bd3153a24b50743a324e /src/core/lib/iomgr/tcp_server_posix.c | |
parent | a3e7bd85c064da9a1011fd31209e5af6a7ff8f38 (diff) | |
parent | 2c779d64db4b4e460c697b59170f85135d552db5 (diff) |
Merge remote-tracking branch 'upstream/master' into handshaker_api
Diffstat (limited to 'src/core/lib/iomgr/tcp_server_posix.c')
-rw-r--r-- | src/core/lib/iomgr/tcp_server_posix.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c index 38ebd2dbcb..ea8d241154 100644 --- a/src/core/lib/iomgr/tcp_server_posix.c +++ b/src/core/lib/iomgr/tcp_server_posix.c @@ -90,10 +90,12 @@ struct grpc_tcp_listener { grpc_closure read_closure; grpc_closure destroyed_closure; struct grpc_tcp_listener *next; - /* 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. */ + /* sibling is a linked list of all listeners for a given port. add_port and + clone_port place all new listeners in the same sibling list. A member of + the 'sibling' list is also a member of the 'next' list. The head of each + sibling list has is_sibling==0, and subsequent members of sibling lists + have is_sibling==1. is_sibling allows separate sibling lists to be + identified while iterating through 'next'. */ struct grpc_tcp_listener *sibling; int is_sibling; }; @@ -306,7 +308,7 @@ static grpc_error *prepare_socket(int fd, const struct sockaddr *addr, GPR_ASSERT(fd >= 0); - if (so_reuseport) { + if (so_reuseport && !grpc_is_unix_socket(addr)) { err = grpc_set_socket_reuse_port(fd, 1); if (err != GRPC_ERROR_NONE) goto error; } @@ -480,6 +482,9 @@ static grpc_error *add_socket_to_server(grpc_tcp_server *s, int fd, return err; } +/* Insert count new listeners after listener. Every new listener will have the + same listen address as listener (SO_REUSEPORT must be enabled). Every new + listener is a sibling of listener. */ static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) { grpc_tcp_listener *sp = NULL; char *addr_str; @@ -506,6 +511,11 @@ static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) { sp = gpr_malloc(sizeof(grpc_tcp_listener)); sp->next = listener->next; listener->next = sp; + /* sp (the new listener) is a sibling of 'listener' (the original + listener). */ + sp->is_sibling = 1; + sp->sibling = listener->sibling; + listener->sibling = sp; sp->server = listener->server; sp->fd = fd; sp->emfd = grpc_fd_create(fd, name); @@ -514,8 +524,6 @@ static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) { sp->port = port; sp->port_index = listener->port_index; sp->fd_index = listener->fd_index + count - i; - sp->is_sibling = 1; - sp->sibling = listener->is_sibling ? listener->sibling : listener; GPR_ASSERT(sp->emfd); while (listener->server->tail->next != NULL) { listener->server->tail = listener->server->tail->next; @@ -685,7 +693,8 @@ void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s, s->pollset_count = pollset_count; sp = s->head; while (sp != NULL) { - if (s->so_reuseport && pollset_count > 1) { + if (s->so_reuseport && !grpc_is_unix_socket(&sp->addr.sockaddr) && + pollset_count > 1) { GPR_ASSERT(GRPC_LOG_IF_ERROR( "clone_port", clone_port(sp, (unsigned)(pollset_count - 1)))); for (i = 0; i < pollset_count; i++) { |