aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib/iomgr/tcp_server_posix.c
diff options
context:
space:
mode:
authorGravatar Mark D. Roth <roth@google.com>2016-08-11 08:52:02 -0700
committerGravatar Mark D. Roth <roth@google.com>2016-08-11 08:52:02 -0700
commitfddb3d3451940c35990da8191a4345723a90da2d (patch)
tree48e0630c57e9cdf20577bd3153a24b50743a324e /src/core/lib/iomgr/tcp_server_posix.c
parenta3e7bd85c064da9a1011fd31209e5af6a7ff8f38 (diff)
parent2c779d64db4b4e460c697b59170f85135d552db5 (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.c25
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++) {