Lightness Races in Orbit Lightness Races in Orbit - 28 days ago 7
C++ Question

How can I interrupt an infinite sigtimedwait?

My program has an event loop disciplined by

epoll
(for I/O) and condition variables (for other message activity), as well as a worker thread responsible for catching signals (
SIGINT
,
SIGTERM
,
SIGHUP
).
SIGINT
,
SIGTERM
,
SIGHUP
and
SIGPIPE
are blocked in all other threads.

My
epoll_wait
calls have a 500ms timeout, but I am trying to reduce context switches and use an infinite
epoll_wait
instead, woken by pipe activity when the main thread decides it's time to quit the program and the event loop should be stopped.

Similarly, my
sigtimedwait
call has a 500ms timeout (and checks a
std::atomic<bool>
after each call, to see whether it needs to stop), and I'd like to replace this with something that doesn't need to keep waking to check for interruption.

Can I raise a signal from the main thread to the signal-watching thread to achieve this, or something like that? Or is there a better way to catch signals in this day and age?

This is on CentOS 6 and 7 (though a general POSIX solution would be preferred — bonus points for mere standard C++11!).

Answer

Use signal file descriptors, instead of signal handlers.

Instead of a signal handler, the receipt of a signal is will now be done by reading from a file descriptor, which is epollable, and can be handled as part of your epoll set.

Yes, that's the better way to catch signals, on Linux, in this day and age.