Skip to content
Snippets Groups Projects
Commit 2da02964 authored by Craig Tiller's avatar Craig Tiller
Browse files

Eliminate need for SIGPIPE handling

parent ae35546d
No related branches found
No related tags found
No related merge requests found
......@@ -80,6 +80,7 @@
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_GETPID_IN_UNISTD_H 1
#define GPR_HAVE_MSG_NOSIGNAL 1
#elif defined(__linux__)
#ifndef _BSD_SOURCE
#define _BSD_SOURCE
......@@ -124,6 +125,7 @@
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_GETPID_IN_UNISTD_H 1
#define GPR_HAVE_MSG_NOSIGNAL 1
#ifdef _LP64
#define GPR_ARCH_64 1
#else /* _LP64 */
......@@ -155,6 +157,7 @@
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_GETPID_IN_UNISTD_H 1
#define GPR_HAVE_SO_NOSIGPIPE 1
#ifdef _LP64
#define GPR_ARCH_64 1
#else /* _LP64 */
......@@ -180,6 +183,7 @@
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_GETPID_IN_UNISTD_H 1
#define GPR_HAVE_SO_NOSIGPIPE 1
#ifdef _LP64
#define GPR_ARCH_64 1
#else /* _LP64 */
......
......@@ -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);
......
......@@ -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
......
......@@ -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;
......
......@@ -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);
......
......@@ -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));
......
......@@ -49,10 +49,6 @@ static int seed(void) { return _getpid(); }
#endif
void grpc_test_init(int argc, char **argv) {
#ifndef GPR_WIN32
/* disable SIGPIPE */
signal(SIGPIPE, SIG_IGN);
#endif
gpr_log(GPR_DEBUG, "test slowdown: machine=%f build=%f total=%f",
GRPC_TEST_SLOWDOWN_MACHINE_FACTOR, GRPC_TEST_SLOWDOWN_BUILD_FACTOR,
GRPC_TEST_SLOWDOWN_FACTOR);
......
......@@ -138,7 +138,6 @@ static void RunQPS() {
} // namespace grpc
int main(int argc, char** argv) {
signal(SIGPIPE, SIG_IGN);
using namespace grpc::testing;
RunSynchronousStreamingPingPong();
RunSynchronousUnaryPingPong();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment