From 7dcd09692cd3d916cb8e76c4bad3e7bf14ed30fb Mon Sep 17 00:00:00 2001 From: Dennis Klein Date: Tue, 19 Sep 2017 18:12:40 +0200 Subject: [PATCH] FairMQ: Move static and interactive control modes to plugin (3) --- fairmq/FairMQDevice.cxx | 105 +-------------------------- fairmq/FairMQDevice.h | 13 +--- fairmq/PluginServices.cxx | 10 +-- fairmq/options/FairMQProgOptions.cxx | 3 - fairmq/plugins/Control.cxx | 4 +- 5 files changed, 10 insertions(+), 125 deletions(-) diff --git a/fairmq/FairMQDevice.cxx b/fairmq/FairMQDevice.cxx index e2a83e99..ac54916f 100644 --- a/fairmq/FairMQDevice.cxx +++ b/fairmq/FairMQDevice.cxx @@ -16,9 +16,6 @@ #include #include -#include // for the InteractiveStateLoop -#include - #include // join/split #include @@ -62,7 +59,7 @@ FairMQDevice::FairMQDevice() , fDefaultTransport() , fInitializationTimeoutInS(120) , fCatchingSignals(false) - , fInteractiveRunning(false) + , fTerminationRequested(false) , fDataCallbacks(false) , fDeviceCmdSockets() , fMsgInputs() @@ -93,7 +90,7 @@ FairMQDevice::FairMQDevice(const fair::mq::tools::Version version) , fDefaultTransport() , fInitializationTimeoutInS(120) , fCatchingSignals(false) - , fInteractiveRunning(false) + , fTerminationRequested(false) , fDataCallbacks(false) , fDeviceCmdSockets() , fMsgInputs() @@ -138,7 +135,6 @@ void FairMQDevice::SignalHandler(int signal) ChangeState(END); // exit(EXIT_FAILURE); - fInteractiveRunning = false; LOG(INFO) << "Exiting."; } else @@ -1136,103 +1132,6 @@ void FairMQDevice::LogSocketRates() // LOG(DEBUG) << "FairMQDevice::LogSocketRates() stopping"; } -void FairMQDevice::InteractiveStateLoop() -{ - fInteractiveRunning = true; - char c; // hold the user console input - pollfd cinfd[1]; - cinfd[0].fd = fileno(stdin); - cinfd[0].events = POLLIN; - - struct termios t; - tcgetattr(STDIN_FILENO, &t); // get the current terminal I/O structure - t.c_lflag &= ~ICANON; // disable canonical input - tcsetattr(STDIN_FILENO, TCSANOW, &t); // apply the new settings - - PrintInteractiveStateLoopHelp(); - - while (fInteractiveRunning) - { - if (poll(cinfd, 1, 500)) - { - if (!fInteractiveRunning) - { - break; - } - - cin >> c; - - switch (c) - { - case 'i': - LOG(INFO) << "[i] init device"; - ChangeState(INIT_DEVICE); - break; - case 'j': - LOG(INFO) << "[j] init task"; - ChangeState(INIT_TASK); - break; - case 'p': - LOG(INFO) << "[p] pause"; - ChangeState(PAUSE); - break; - case 'r': - LOG(INFO) << "[r] run"; - ChangeState(RUN); - break; - case 's': - LOG(INFO) << "[s] stop"; - ChangeState(STOP); - break; - case 't': - LOG(INFO) << "[t] reset task"; - ChangeState(RESET_TASK); - break; - case 'd': - LOG(INFO) << "[d] reset device"; - ChangeState(RESET_DEVICE); - break; - case 'h': - LOG(INFO) << "[h] help"; - PrintInteractiveStateLoopHelp(); - break; - // case 'x': - // LOG(INFO) << "[x] ERROR"; - // ChangeState(ERROR_FOUND); - // break; - case 'q': - LOG(INFO) << "[q] end"; - - ChangeState(STOP); - - ChangeState(RESET_TASK); - WaitForEndOfState(RESET_TASK); - - ChangeState(RESET_DEVICE); - WaitForEndOfState(RESET_DEVICE); - - ChangeState(END); - - if (CheckCurrentState(EXITING)) - { - fInteractiveRunning = false; - } - - LOG(INFO) << "Exiting."; - break; - default: - LOG(INFO) << "Invalid input: [" << c << "]"; - PrintInteractiveStateLoopHelp(); - break; - } - } - } - - tcgetattr(STDIN_FILENO, &t); // get the current terminal I/O structure - t.c_lflag |= ICANON; // re-enable canonical input - tcsetattr(STDIN_FILENO, TCSANOW, &t); // apply the new settings -} - void FairMQDevice::Unblock() { FairMQChannel::fInterrupted = true; diff --git a/fairmq/FairMQDevice.h b/fairmq/FairMQDevice.h index e1862c20..f66b82a6 100644 --- a/fairmq/FairMQDevice.h +++ b/fairmq/FairMQDevice.h @@ -299,16 +299,6 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable /// Waits for the first initialization run to finish void WaitForInitialValidation(); - /// Starts interactive (console) loop for controlling the device - /// Works only when running in a terminal. Running in background would exit, because no interactive input (std::cin) is possible. - void InteractiveStateLoop(); - /// Prints the available commands of the InteractiveStateLoop() - void PrintInteractiveStateLoopHelp() - { - LOG(INFO) << "Use keys to control the state machine:"; - LOG(INFO) << "[h] help, [p] pause, [r] run, [s] stop, [t] reset task, [d] reset device, [q] end, [j] init task, [i] init device"; - } - /// Set Device properties stored as strings /// @param key Property key /// @param value Property value @@ -569,8 +559,7 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable /// Signal handler void SignalHandler(int signal); bool fCatchingSignals; - // Interactive state loop helper - std::atomic fInteractiveRunning; + std::atomic fTerminationRequested; bool fDataCallbacks; std::unordered_map fDeviceCmdSockets; ///< Sockets used for the internal unblocking mechanism diff --git a/fairmq/PluginServices.cxx b/fairmq/PluginServices.cxx index c57d0438..d76857ec 100644 --- a/fairmq/PluginServices.cxx +++ b/fairmq/PluginServices.cxx @@ -100,8 +100,8 @@ auto PluginServices::ChangeDeviceState(const std::string& controller, const Devi else { throw DeviceControlError{tools::ToString( - "Plugin ", controller, " is not allowed to change device states. ", - "Currently, plugin ", fDeviceController, " has taken control." + "Plugin '", controller, "' is not allowed to change device states. ", + "Currently, plugin '", fDeviceController, "' has taken control." )}; } } @@ -121,8 +121,8 @@ auto PluginServices::TakeDeviceControl(const std::string& controller) -> void else { throw DeviceControlError{tools::ToString( - "Plugin ", controller, " is not allowed to take over control. ", - "Currently, plugin ", fDeviceController, " has taken control." + "Plugin '", controller, "' is not allowed to take over control. ", + "Currently, plugin '", fDeviceController, "' has taken control." )}; } @@ -139,7 +139,7 @@ auto PluginServices::ReleaseDeviceControl(const std::string& controller) -> void } else { - throw DeviceControlError{tools::ToString("Plugin ", controller, " cannot release control because it has not taken over control.")}; + throw DeviceControlError{tools::ToString("Plugin '", controller, "' cannot release control because it has not taken over control.")}; } } diff --git a/fairmq/options/FairMQProgOptions.cxx b/fairmq/options/FairMQProgOptions.cxx index af923d32..2c9627a2 100644 --- a/fairmq/options/FairMQProgOptions.cxx +++ b/fairmq/options/FairMQProgOptions.cxx @@ -323,7 +323,6 @@ void FairMQProgOptions::InitOptionDescription() ("io-threads", po::value()->default_value(1), "Number of I/O threads.") ("transport", po::value()->default_value("zeromq"), "Transport ('zeromq'/'nanomsg').") ("config", po::value()->default_value("static"), "Config source ('static'/).") - ("control", po::value()->default_value("interactive"), "States control ('interactive'/'static'/).") ("network-interface", po::value()->default_value("default"), "Network interface to bind on (e.g. eth0, ib0..., default will try to detect the interface of the default route).") ("config-key", po::value(), "Use provided value instead of device id for fetching the configuration from the config file.") ("catch-signals", po::value()->default_value(1), "Enable signal handling (1/0).") @@ -341,7 +340,6 @@ void FairMQProgOptions::InitOptionDescription() ("io-threads", po::value()->default_value(1), "Number of I/O threads.") ("transport", po::value()->default_value("zeromq"), "Transport ('zeromq'/'nanomsg').") ("config", po::value()->default_value("static"), "Config source ('static'/).") - ("control", po::value()->default_value("interactive"), "States control ('interactive'/'static'/).") ("network-interface", po::value()->default_value("default"), "Network interface to bind on (e.g. eth0, ib0..., default will try to detect the interface of the default route).") ("config-key", po::value(), "Use provided value instead of device id for fetching the configuration from the config file.") ("catch-signals", po::value()->default_value(1), "Enable signal handling (1/0).") @@ -361,7 +359,6 @@ void FairMQProgOptions::InitOptionDescription() ("io-threads", po::value()->default_value(1), "Number of I/O threads.") ("transport", po::value()->default_value("zeromq"), "Transport ('zeromq'/'nanomsg').") ("config", po::value()->default_value("static"), "Config source ('static'/).") - ("control", po::value()->default_value("interactive"), "States control ('interactive'/'static'/).") ("network-interface", po::value()->default_value("default"), "Network interface to bind on (e.g. eth0, ib0..., default will try to detect the interface of the default route).") ("config-key", po::value(), "Use provided value instead of device id for fetching the configuration from the config file.") ("catch-signals", po::value()->default_value(1), "Enable signal handling (1/0).") diff --git a/fairmq/plugins/Control.cxx b/fairmq/plugins/Control.cxx index 4b38735f..648c17a8 100644 --- a/fairmq/plugins/Control.cxx +++ b/fairmq/plugins/Control.cxx @@ -51,6 +51,7 @@ Control::Control(const string name, const Plugin::Version version, const string } 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(); } } @@ -59,8 +60,7 @@ auto ControlPluginProgramOptions() -> Plugin::ProgOptions { auto pluginOptions = boost::program_options::options_description{"Control (builtin) Plugin"}; pluginOptions.add_options() - ("ctrlmode", boost::program_options::value(), "Control mode, 'static' or 'interactive'"); - // should rename to --control and remove control from device options ? + ("control", boost::program_options::value()->default_value("interactive"), "Control mode, 'static' or 'interactive'"); return pluginOptions; }