Search code examples
macospthreadsgrand-central-dispatchdarwinmach

pthread_kill to a GCD-managed thread


I am attempting to send a signal to a specific thread with pthread_kill. I use pthread_from_mach_thread_np() to get a handle and then use pthread_kill to send the signal.

This worked well in my other testing, but now I see that when attempting to signal a thread internally created by GCD, I get a return code of 45 from pthread_kill.

GCD API that spawned that thread:

dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{ ... });

Any reason this is happening?

—-

To add some further information, I am not attempting to kill threads. pthread_kill() is the standard POSIX API to send signals to threads. If a signal handler is installed, the thread’s context is switched with a trampoline to the handler.

While what I attempt to achieve using my signal handler can be achieved in better ways, this is not in question here. Even if for purely academic reasons, I would like to understand what is going on here internally.


Solution

  • The pthread_kill() API is specifically disallowed on workqueue threads (the worker threads underlying GCD) and returns ENOTSUP for such threads.

    This is primarily intended to prevent execution of arbitrary signal handlers in the context of code that may not expect it (since these threads are a shared resource used by many independent subsystems in a process), as well as to abstract away that execution context so that the system has the freedom to change it in the future.

    You can see the details of how this is achieved in the implementation.