Stiffstream / sobjectizer

An implementation of Actor, Publish-Subscribe, and CSP models in one rather small C++ framework. With performance, quality, and stability proved by years in the production.

Home Page:https://stiffstream.com/en/products/sobjectizer.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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!