From 81697bc2200c1e8a55689f99b7d4763e999abaac Mon Sep 17 00:00:00 2001 From: Lorenz Bauer Date: Wed, 15 Feb 2017 18:58:05 +0000 Subject: [PATCH] ITS#8590 LMDB: Use F_SETNOSIGPIPE on OS X It seems like OS X delivers SIGPIPE to the whole process, instead of the generating thread, as on other UNIXes. Therefore the current code sometimes works, but mostly doesn't, since the call to sigwait doesn't happen quickly enough. Instead of masking SIGPIPE, we use an OS X specific fcntl to disable SIGPIPE for that particular fd. --- libraries/liblmdb/mdb.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index c8e057463e..dbb1504683 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -11077,7 +11077,14 @@ mdb_env_copythr(void *arg) #else ssize_t len; size_t w2; -#ifdef SIGPIPE +#ifdef F_SETNOSIGPIPE + /* OS X delivers SIGPIPE to the whole process, not the thread that caused it. + * Disable SIGPIPE using platform specific fcntl. + */ + int enabled = 1; + if ((rc = fcntl(my->mc_fd, F_SETNOSIGPIPE, &enabled)) != 0) + my->mc_error = errno; +#elif defined SIGPIPE sigset_t set; sigemptyset(&set); sigaddset(&set, SIGPIPE); @@ -11101,15 +11108,6 @@ again: DO_WRITE(rc, my->mc_fd, ptr, w2, len); if (!rc) { rc = ErrCode(); -#if defined(SIGPIPE) && !defined(_WIN32) - if (rc == EPIPE) { - /* Collect the pending SIGPIPE, otherwise at least OS X - * gives it to the process on thread-exit (ITS#8504). - */ - int tmp; - sigwait(&set, &tmp); - } -#endif break; } else if (len > 0) { rc = MDB_SUCCESS;