How to safely catch and forward a OS signal (SIGINT, SIGHUP, etc)
jcarrano opened this issue · comments
I need to be able to stop the environment when the application receives a SIGINT/SIGQUIT and send a message to a component to reload the configuration when SIGHUP is received.
Doing this seems to work:
auto stop_app = [](int signal) -> void {
main_env->stop();
};
...
std::signal(SIGTERM, stop_app);
However, reading the code in environment_t::stop() I suspect it is not safe to call from the context of an async signal. The same goes for sending a message to a mbox/mchain, AFAIU there is the possibility of a deadlock if the signal just happens to be delivered while the message box mutex is being held.
How can OS signals be handled safely. I can only think of a few options:
- Have a dedicated thread to handle signals.
- Make a custom implementation of mchain that uses a self-pipe.
- Periodically poll signals through a signalfd.
- Wait on a signalfd from another thread and send a message though a mchain.
- Make a custom timer thread implementation that replaces the condition variable by an eventfd or self-pipe, so that it can simultaneously wait on other FDs or receive data from a signal handler.
Hi!
You can find an approach that we used earlier in our arataga project:
Signal handling loop: https://github.com/Stiffstream/arataga/blob/b6e1720dd2df055949847425f12bb1af56edbe83/arataga/main.cpp#L602-L639
The core part of the main function: https://github.com/Stiffstream/arataga/blob/b6e1720dd2df055949847425f12bb1af56edbe83/arataga/main.cpp#L866-L877
Some of approaches you mentioned should also work and don't seem to be complex in implementation, for example:
- Periodically poll signals through a signalfd.
- Wait on a signalfd from another thread and send a message though a mchain.
But this case:
- Make a custom timer thread implementation that replaces the condition variable by an eventfd or self-pipe, so that it can simultaneously wait on other FDs or receive data from a signal handler.
seems to be overkill in implementation complexity.
Thanks for the quick response. I had failed to notice that one can use a custom loop through a wrapped env!