signal handlers and dispatch_main

I need XPC at the beginnning of my process to get startup parameters, but after that I don't need it.
I call dispatch_main so that my XPC communication can happen.
After my communication through XPC has finished I call glib's main event loop to call common glib code from inside the xpc message handler.

I need signal handlers to catch TERM and INT.

My dispatch signal handlers get called if I don't call the glib event loop, but don't if I do.
My sigaction handlers don't get called if I call dispatch_main but do if I just go straight into the glib main loop.


Is there a way to have a dispatch loop that I can exit so that I'm not calling glib's event loop inside dispatch_main?
It looks like setting up a dispatch signal event source creates a signal file descriptor, and that prevents the attempt to sigaction by the normal linux code. However, I'm unsure why I don't then get the signals through my dispatch signal event handler. I suspect it is because by calling glib's main event loop dispatch loses control, or the thread that the signal event handlers want to send on is lost or something like that.

Accepted Reply

I think there is some conflation here. The fact that you are calling dispatchmain() is likely not relevant to the problem at hand.

My dispatch signal handlers get called if I don't call the glib event loop, but don't if I do.

When you set up a dispatch signal handler, which queue are you targetting that signal handler source to? I suspect glib's event loop is run on a serial queue A, thereby blocking execution of any other blocks on queue A until the event loop returns. And your dispatch signal handler is also targetting queue A and is therefore blocked behind your glib's event loop.

You need to target your sources on a different queue if you plan on blocking queue A with glib's event loop.

My sigaction handlers don't get called if I call dispatch

main but do if I just go straight into the glib main loop.dispatch_main simply exits the main thread via pthread_exit(). It does not create any signal masks which block delivery of signals to your process.

Replies

What does glib’s main event loop use under the covers?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

WWDC runs Mon, 22 Jun through to Fri, 26 Jun. During that time all of DTS will be busy with conference duties.

I think there is some conflation here. The fact that you are calling dispatchmain() is likely not relevant to the problem at hand.

My dispatch signal handlers get called if I don't call the glib event loop, but don't if I do.

When you set up a dispatch signal handler, which queue are you targetting that signal handler source to? I suspect glib's event loop is run on a serial queue A, thereby blocking execution of any other blocks on queue A until the event loop returns. And your dispatch signal handler is also targetting queue A and is therefore blocked behind your glib's event loop.

You need to target your sources on a different queue if you plan on blocking queue A with glib's event loop.

My sigaction handlers don't get called if I call dispatch

main but do if I just go straight into the glib main loop.dispatch_main simply exits the main thread via pthread_exit(). It does not create any signal masks which block delivery of signals to your process.
Based on your description, it also sounds like glib may install its own signal handling. That would be another area of investigation to determine why your own signal handler isn’t being invoked.
Thanks for the responses. I am looking at making glib use dispatch for event handling as potentially a performance enhancement. I've downloaded the dispatch source and looked through it a good bit and that has been somewhat helpful. Some really gnarly macros live in there. You've given me an idea for a path around the immediate problem. I THOUGHT I'd tried it when I ran into the problem initially, but I'll need to verify.