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