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.
This commit is contained in:
Lorenz Bauer 2017-02-15 18:58:05 +00:00 committed by Howard Chu
parent 63698faf2c
commit 81697bc220

View file

@ -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;