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

Dave Zarzycki zarzycki at apple.com
Mon Jul 4 18:03:48 PDT 2011


On Jul 4, 2011, at 5:17 PM, DrPizza wrote:

>> Yes. That helps us avoid two system calls per callback from the
>> pthread_workqueue.
> 
> OK, makes sense. Do you know if there any other "special" properties of the workqueue threads that might be significant?

I believe that some of the "don't do that" section of the dispatch man pages are actually enforced. For example, calling pthread_exit() on a GCD thread will probably give an error. It is worth verifying.

> 
>> I'm not sure I understand the question.
> Well, at the moment _dispatch_pthread_sigmask() looks like it's picking a specific limited set of signals to block off. If the intent is to block every blockable signal, doesn't sigfillset() generate a suitable mask, and more explicitly express the notion of "block everything".

No.

sigfillset() does exactly what it says: it simply fills the set. It doesn't know why the set is being created.

On Mac OS X and iOS, some signals are only deliverable on the thread that they were generated from (SIGILL, SIGFPE, SIGBUS, SIGSEGV, etc), therefore, we shouldn't mask those off. Someday, if/when the Mac OS X / iOS kernel supports delivering those signals to any available thread, then we can fully mask every signal on GCD threads.

> 
>> In practice, what we found was that programs that installed signal handlers
>> via signal()/sigaction() often made the assumption that there will always be
>> a thread available to handle the signal. In other words, deferring
>> traditional Unix signal handlers until a worker thread was idle could cause
>> apps to hang. That is why GCD keeps a dedicated signal handling thread
>> running. However, we cannot blindly create this helper thread when
>> libdispatch is initialized because other programs [dubiously] assume that
>> libraries do not leave lingering helper threads. Therefore, GCD only creates
>> the helper thread if the main thread exits (because the main thread doesn't
>> start out with any masked signals – technically it could, but in practice it
>> doesn't happen.)
> Ah, I get you. The thread stuck in the loop is there to stand in for the (now exited) main thread, to ensure that signals have somewhere to drain.

Yup.

> Might there be situations where the main thread's mask is changed (for example, if an application wants to handle specific signals on a specific threads), and if so, might not a slightly better behaviour be for the signal-draining thread be to use the mask of the main thread, not the empty, accept-anything mask?

In theory, yes – but in practice, no. Such a usage pattern would be incompatible with GCD (or any other OS provided thread pool / event engine), because the design would require extremely discipline. (Knowing about *all* threads within a process and *carefully* controlling their respective signal masks *all* of the time, etc)

davez


More information about the libdispatch-dev mailing list