[libdispatch-dev] What's with this sigsuspend stuff?

Dave Zarzycki zarzycki at apple.com
Mon Jul 4 13:24:59 PDT 2011

On Jul 4, 2011, at 10:36 AM, DrPizza wrote:

> I'm trying to understand the purpose of _dispatch_sigsuspend() [1], but for the life of me, I cannot see what it is.
> To the best of my knowledge, sigsuspend() blocks a single thread (not an entire process, per POSIX [2])…


That above first part correct…

> …suspending it until one of the signals in the sigset_t is sent to that thread.

…but the line above is backwards. The API changes the signal mask for the duration of the call to that of the passed in parameter. Therefore if an empty set is passed in, then all signals are unblocked for the duration of the call.

> sigsuspend() requires that the sigset_t be properly initialized (using either sigemptyset() or sigfillset()) and then, optionally, modified (using sigaddset() or sigdelset()). The behaviour is undefined if this does not occur. _dispatch_sigsuspend() does not properly initialize the sigset_t, instead passing it straight to sigsuspend(). So whatever the purpose of this function is, it probably isn't doing it properly.

On all of the platforms that we know of, the result of sigemptyset() is the same as bzero(&set, sizeof(set)), and static variables default initialize to zero. So we're okay.

> But then, what is that purpose?

To dequeue pending signals installed via signal()/sigaction() that would otherwise be blocked in a pure GCD app. This is because GCD threads block all maskable signals (see _dispatch_worker_thread() in the same file). This behavior helps all code that uses GCD avoid spurious EINTR errors from Unix system calls (which are often not tested for).


More information about the libdispatch-dev mailing list