[libdispatch-dev] What's with this sigsuspend stuff?
DrPizza at quiscalusmexicanus.org
Mon Jul 4 17:17:21 PDT 2011
> Yes. That helps us avoid two system calls per callback from the
OK, makes sense. Do you know if there any other "special" properties of the workqueue threads that might be significant?
> 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".
> 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.
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?
> I don't know how Windows supports POSIX, but that sounds reasonable.
The Windows POSIX subsystem has "proper" signal handling, but it is almost entirely separate from the Win32 subsystem, and so not the target of my port. The VC++ C Runtime does include some basic signal functionality, but it's entirely fake; signals can't be delivered from outside the process, and if they're raised in-process, the signal handler is directly executed on the raising thread. There's no masking or notion of delivering signals to other threads.
The one exception is ctrl-c/ctrl-break, and the system spawns a dedicated thread within the process to handle these anyway, so again there's no masking or any equivalent concepts.
More information about the libdispatch-dev