Improve Catching Signals
I realized that in some cases the SIGINT
signal seem to have been ignored. It turned out that these were cases when the event submission loop had already finished and all events where submitted to the thread pool's buffer. In that case, the main thread was waiting at thread_pool->wait()
for all events to finish and with no way of interrupting.
Therefore I slightly changed the setup: The thread pool is now a data member of the ModuleManager
class, but will still only exist within the run()
method and be a nullptr
outside of that. Making it a data member allows to directly call ThreadPool::destroy()
right from the method invoked by the signal, i.e. ModuleManager::terminate()
without any polling for the status of terminate_
as done previously. The event submission loop is broken anyway by checking for terminate_ == true
as before.
The printing of the termination message has been changed to be signal-safe - write()
is while our logger with all its std::cout
shenanigans is not.
I'm not sure this is all there is to do for really properly handling signals, it's a deep water. As stated in A Research UNIX Reader: Annotated Excerpts from the Programmer’s Manual, 1971-1986::
A simple unconditional kill was available to terminate rogue programs in the background (v2). In v5 kill was generalized to send arbitrary signals. Never, however, was the basically unstructured signal-kill mechanism regarded as a significant means of interprocess communication.
Maybe at some point we should dig a bit deeper and make sure our spawned threads don't listen to signals?
(cc) @kwolters