Lightness Races in Orbit Lightness Races in Orbit - 1 year ago 81
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 Source

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download