From 88b3b8ef1895dc0cb2b0a70141b2866ab8df1ce7 Mon Sep 17 00:00:00 2001 From: Dennis Klein Date: Wed, 20 Sep 2017 18:10:56 +0200 Subject: [PATCH] FairMQ: Make sure --catch-signals is always handled --- fairmq/plugins/Control.cxx | 63 +++++++++++++++++++------------------- fairmq/plugins/Control.h | 2 +- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/fairmq/plugins/Control.cxx b/fairmq/plugins/Control.cxx index 8babf320..0c2a4bb1 100644 --- a/fairmq/plugins/Control.cxx +++ b/fairmq/plugins/Control.cxx @@ -17,6 +17,7 @@ using namespace std; namespace { + // ugly global state, but std::signal gives us no other choice std::function gSignalHandlerClosure; extern "C" auto signal_handler(int signal) -> void @@ -62,24 +63,24 @@ Control::Control(const string name, const Plugin::Version version, const string LOG(ERROR) << "Unrecognized control mode '" << control << "' requested. " << "Ignoring and falling back to static control mode."; fControllerThread = thread(&Control::StaticMode, this); } - - LOG(DEBUG) << "catch-signals: " << GetProperty("catch-signals"); - if (GetProperty("catch-signals") > 0) - { - gSignalHandlerClosure = bind(&Control::SignalHandler, this, placeholders::_1); - signal(SIGINT, signal_handler); - signal(SIGTERM, signal_handler); - } - else - { - LOG(WARN) << "Signal handling (e.g. Ctrl-C) has been deactivated."; - } } catch (PluginServices::DeviceControlError& e) { // If we are here, it means another plugin has taken control. That's fine, just print the exception message and do nothing else. LOG(DEBUG) << e.what(); } + + LOG(DEBUG) << "catch-signals: " << GetProperty("catch-signals"); + if (GetProperty("catch-signals") > 0) + { + gSignalHandlerClosure = bind(&Control::SignalHandler, this, placeholders::_1); + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + } + else + { + LOG(WARN) << "Signal handling (e.g. Ctrl-C) has been deactivated."; + } } auto ControlPluginProgramOptions() -> Plugin::ProgOptions @@ -96,15 +97,6 @@ auto Control::InteractiveMode() -> void { try { - SubscribeToDeviceStateChange([&](DeviceState newState) - { - { - lock_guard lock{fEventsMutex}; - fEvents.push(newState); - } - fNewEvent.notify_one(); - }); - RunStartupSequence(); char input; // hold the user console input @@ -226,15 +218,6 @@ auto Control::StaticMode() -> void { try { - SubscribeToDeviceStateChange([&](DeviceState newState) - { - { - lock_guard lock{fEventsMutex}; - fEvents.push(newState); - } - fNewEvent.notify_one(); - }); - RunStartupSequence(); { @@ -261,7 +244,6 @@ auto Control::StaticMode() -> void auto Control::SignalHandler(int signal) -> void { - if (!fDeviceTerminationRequested) { fDeviceTerminationRequested = true; @@ -271,6 +253,16 @@ auto Control::SignalHandler(int signal) -> void LOG(INFO) << "Received device shutdown request (signal " << signal << ")."; LOG(INFO) << "Waiting for graceful device shutdown. Hit Ctrl-C again to abort immediately."; + UnsubscribeFromDeviceStateChange(); // In case, static or interactive mode have subscribed already + SubscribeToDeviceStateChange([&](DeviceState newState) + { + { + lock_guard lock{fEventsMutex}; + fEvents.push(newState); + } + fNewEvent.notify_one(); + }); + fSignalHandlerThread = thread(&Control::RunShutdownSequence, this); } else @@ -317,6 +309,15 @@ auto Control::RunShutdownSequence() -> void auto Control::RunStartupSequence() -> void { + SubscribeToDeviceStateChange([&](DeviceState newState) + { + { + lock_guard lock{fEventsMutex}; + fEvents.push(newState); + } + fNewEvent.notify_one(); + }); + ChangeDeviceState(DeviceStateTransition::InitDevice); while (WaitForNextState() != DeviceState::DeviceReady) {} ChangeDeviceState(DeviceStateTransition::InitTask); diff --git a/fairmq/plugins/Control.h b/fairmq/plugins/Control.h index 85a891aa..7b445c09 100644 --- a/fairmq/plugins/Control.h +++ b/fairmq/plugins/Control.h @@ -55,7 +55,7 @@ auto ControlPluginProgramOptions() -> Plugin::ProgOptions; REGISTER_FAIRMQ_PLUGIN( Control, // Class name control, // Plugin name (string, lower case chars only) - (Plugin::Version{1,0,0}), // Version + (Plugin::Version{1,0,1}), // Version "FairRootGroup ", // Maintainer "https://github.com/FairRootGroup/FairRoot", // Homepage ControlPluginProgramOptions // Free function which declares custom program options for the plugin