diff options
author | Craig Tiller <ctiller@google.com> | 2015-05-06 16:14:25 -0700 |
---|---|---|
committer | Craig Tiller <ctiller@google.com> | 2015-05-06 16:14:25 -0700 |
commit | 2da029647803aa26e393faa1422beecae7d1805a (patch) | |
tree | f6d1add6d08583d22cd54f25147c39eba11b36ff /src/core/iomgr | |
parent | ae35546ddaf6225bc35545df05b65a560e6d52f3 (diff) |
Eliminate need for SIGPIPE handling
Diffstat (limited to 'src/core/iomgr')
-rw-r--r-- | src/core/iomgr/socket_utils_common_posix.c | 13 | ||||
-rw-r--r-- | src/core/iomgr/socket_utils_posix.h | 5 | ||||
-rw-r--r-- | src/core/iomgr/tcp_client_posix.c | 3 | ||||
-rw-r--r-- | src/core/iomgr/tcp_posix.c | 8 | ||||
-rw-r--r-- | src/core/iomgr/tcp_server_posix.c | 5 |
5 files changed, 31 insertions, 3 deletions
diff --git a/src/core/iomgr/socket_utils_common_posix.c b/src/core/iomgr/socket_utils_common_posix.c index 3c8cafa315..a9af594700 100644 --- a/src/core/iomgr/socket_utils_common_posix.c +++ b/src/core/iomgr/socket_utils_common_posix.c @@ -76,6 +76,19 @@ int grpc_set_socket_nonblocking(int fd, int non_blocking) { return 1; } +int grpc_set_socket_no_sigpipe_if_possible(int fd) { +#ifdef GPR_HAVE_SO_NOSIGPIPE + int val = 1; + int newval; + socklen_t intlen = sizeof(newval); + return 0 == setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof(val)) && + 0 == getsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &newval, &intlen) && + (newval != 0) == val; +#else + return 1; +#endif +} + /* set a socket to close on exec */ int grpc_set_socket_cloexec(int fd, int close_on_exec) { int oldflags = fcntl(fd, F_GETFD, 0); diff --git a/src/core/iomgr/socket_utils_posix.h b/src/core/iomgr/socket_utils_posix.h index c161082afc..d2a315b462 100644 --- a/src/core/iomgr/socket_utils_posix.h +++ b/src/core/iomgr/socket_utils_posix.h @@ -63,6 +63,11 @@ int grpc_set_socket_low_latency(int fd, int low_latency); state to library users, we turn off IPv6 sockets. */ int grpc_ipv6_loopback_available(void); +/* Tries to set SO_NOSIGPIPE if available on this platform. + Returns 1 on success, 0 on failure. + If SO_NO_SIGPIPE is not available, returns 1. */ +int grpc_set_socket_no_sigpipe_if_possible(int fd); + /* An enum to keep track of IPv4/IPv6 socket modes. Currently, this information is only used when a socket is first created, but diff --git a/src/core/iomgr/tcp_client_posix.c b/src/core/iomgr/tcp_client_posix.c index e20cc3d1b2..2401fe00e4 100644 --- a/src/core/iomgr/tcp_client_posix.c +++ b/src/core/iomgr/tcp_client_posix.c @@ -69,7 +69,8 @@ static int prepare_socket(const struct sockaddr *addr, int fd) { } if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || - (addr->sa_family != AF_UNIX && !grpc_set_socket_low_latency(fd, 1))) { + (addr->sa_family != AF_UNIX && !grpc_set_socket_low_latency(fd, 1)) || + !grpc_set_socket_no_sigpipe_if_possible(fd)) { gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, strerror(errno)); goto error; diff --git a/src/core/iomgr/tcp_posix.c b/src/core/iomgr/tcp_posix.c index 06725fbc89..f7dae5f86c 100644 --- a/src/core/iomgr/tcp_posix.c +++ b/src/core/iomgr/tcp_posix.c @@ -53,6 +53,12 @@ #include <grpc/support/sync.h> #include <grpc/support/time.h> +#ifdef GPR_HAVE_MSG_NOSIGNAL +#define SENDMSG_FLAGS MSG_NOSIGNAL +#else +#define SENDMSG_FLAGS 0 +#endif + /* Holds a slice array and associated state. */ typedef struct grpc_tcp_slice_state { gpr_slice *slices; /* Array of slices */ @@ -461,7 +467,7 @@ static grpc_endpoint_write_status grpc_tcp_flush(grpc_tcp *tcp) { GRPC_TIMER_BEGIN(GRPC_PTAG_SENDMSG, 0); do { /* TODO(klempner): Cork if this is a partial write */ - sent_length = sendmsg(tcp->fd, &msg, 0); + sent_length = sendmsg(tcp->fd, &msg, SENDMSG_FLAGS); } while (sent_length < 0 && errno == EINTR); GRPC_TIMER_END(GRPC_PTAG_SENDMSG, 0); diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c index 7e31f2d7a5..d1cd8a769c 100644 --- a/src/core/iomgr/tcp_server_posix.c +++ b/src/core/iomgr/tcp_server_posix.c @@ -235,7 +235,8 @@ static int prepare_socket(int fd, const struct sockaddr *addr, int addr_len) { if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || (addr->sa_family != AF_UNIX && (!grpc_set_socket_low_latency(fd, 1) || - !grpc_set_socket_reuse_addr(fd, 1)))) { + !grpc_set_socket_reuse_addr(fd, 1))) || + !grpc_set_socket_no_sigpipe_if_possible(fd)) { gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, strerror(errno)); goto error; @@ -296,6 +297,8 @@ static void on_read(void *arg, int success) { } } + grpc_set_socket_no_sigpipe_if_possible(fd); + sp->server->cb( sp->server->cb_arg, grpc_tcp_create(grpc_fd_create(fd), GRPC_TCP_DEFAULT_READ_SLICE_SIZE)); |