Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to safely catch and forward a OS signal (SIGINT, SIGHUP, etc) #47

Closed
jcarrano opened this issue Jun 3, 2022 · 2 comments
Closed

Comments

@jcarrano
Copy link

jcarrano commented Jun 3, 2022

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.
@eao197
Copy link
Member

eao197 commented Jun 3, 2022

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.

@jcarrano
Copy link
Author

jcarrano commented Jun 3, 2022

Thanks for the quick response. I had failed to notice that one can use a custom loop through a wrapped env!

@jcarrano jcarrano closed this as completed Jun 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants