diff --git a/slsDetectorServers/matterhonServer/src/MatterhornApp.cpp b/slsDetectorServers/matterhonServer/src/MatterhornApp.cpp index 4ec30921b..0b6acc72b 100644 --- a/slsDetectorServers/matterhonServer/src/MatterhornApp.cpp +++ b/slsDetectorServers/matterhonServer/src/MatterhornApp.cpp @@ -17,7 +17,9 @@ using namespace sls; -pid_t child_pid = -1; +pid_t pid = -1; + +volatile bool interruption = false; /** * Control+C Interrupt Handler @@ -25,12 +27,16 @@ pid_t child_pid = -1; */ void sigInterruptHandler(int signal) { (void)signal; // suppress unused warning if needed - if (child_pid > 0) { - kill(child_pid, SIGTERM); // tell child to exit + /* + if (pid > 0) { + kill(pid, SIGTERM); // tell child to exit } - std::exit(EXIT_SUCCESS); + */ + interruption = true; // tell parent to exit } +void sigterm_handler(int) { interruption = true; } + // TODO: should be a generic ServerApp for all detectors int main(int argc, char *argv[]) { @@ -48,32 +54,37 @@ int main(int argc, char *argv[]) { // Register Ctrl+C handler std::signal(SIGINT, sigInterruptHandler); + // handle locally on socket crash + signal(SIGPIPE, SIG_IGN); + // handle locally on socket crash // sls::setupSignalHandler(SIGPIPE, SIG_IGN); / what is this? - child_pid = fork(); // fork process for control and stop server + pid = fork(); // fork process for control and stop server - if (child_pid == 0) { + if (pid == 0) { // Stop server Process - signal(SIGPIPE, SIG_IGN); + signal(SIGTERM, sigterm_handler); - // std::signal(SIGTERM, childSigTermHandler); LOG(TLogLevel::logINFOBLUE) << "Stop Server [" << opts.port + 1 << "]"; try { VirtualMatterhornServer stopServer(opts.port + 1); + while (!interruption) { + sleep(1); + } } catch (...) { LOG(TLogLevel::logINFOBLUE) << "Exiting Stop Server [ Tid: " << gettid() << " ]"; // TODO: maybe also terminate the control server !!!! - std::exit(EXIT_FAILURE); + return EXIT_FAILURE; } LOG(TLogLevel::logINFOBLUE) << "Exiting Stop Server [ Tid: " << gettid() << " ]"; LOG(sls::logINFO) << "Exiting Stop Server"; - exit(EXIT_SUCCESS); - } else if (child_pid > 0) { + return EXIT_SUCCESS; + } else if (pid > 0) { + // parent // Control Server Process - signal(SIGPIPE, SIG_IGN); LOG(TLogLevel::logINFOBLUE) << "Control Server [" << opts.port << "]\n"; @@ -81,15 +92,17 @@ int main(int argc, char *argv[]) { VirtualMatterhornServer server( opts.port); // TODO use virtual if compiled with virtual // simulators on + while (!interruption) { + sleep(1); + } } catch (...) { - kill(child_pid, SIGTERM); // tell child to exit + kill(0, SIGTERM); // tell child to exit LOG(sls::logINFOBLUE) << "Exiting [ Tid: " << gettid() << " ]"; - std::exit(EXIT_FAILURE); + return EXIT_FAILURE; } - waitpid(child_pid, nullptr, 0); // wait for child to exit + waitpid(0, nullptr, 0); // wait for child to exit LOG(sls::logINFOBLUE) << "Exiting [ Tid: " << gettid() << " ]"; LOG(sls::logINFO) << "Exiting Detector Server"; - exit(EXIT_SUCCESS); } else { LOG(sls::logERROR) << "Failed to fork process for control and stop server"; diff --git a/slsDetectorServers/slsDetectorServer/include/TCPInterface.h b/slsDetectorServers/slsDetectorServer/include/TCPInterface.h index 6efc05367..9538a3e42 100644 --- a/slsDetectorServers/slsDetectorServer/include/TCPInterface.h +++ b/slsDetectorServers/slsDetectorServer/include/TCPInterface.h @@ -4,7 +4,8 @@ #include "sls/sls_detector_funcs.h" #include -#include +#include +#include #include namespace sls { @@ -22,10 +23,18 @@ class TCPInterface { &processFunction_, const uint16_t portNumber = DEFAULT_TCP_CNTRL_PORTNO); - /// @brief starts the TCP/IP server to listen for client commands + /// @brief creates tcp thread void startTCPServer(); + std::atomic killTcpThread{false}; + private: + /** + * @brief starts the TCP/IP server to listen for client commands and process + * them + */ + void startTCPServerClientConnection(); + /** * @brief decodes the received command and calls the corresponding function * @param function_id The ID of the function recived by the server and to @@ -38,10 +47,14 @@ class TCPInterface { std::function processFunction; + /// @brief TCP/IP port number for the detector server uint16_t portNumber{}; /// @brief socket for TCP/IP communication with the client ServerSocket server; + + /// @brief thread for running the TCP/IP server + std::unique_ptr tcpThread; }; } // namespace sls \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/src/TCPInterface.cpp b/slsDetectorServers/slsDetectorServer/src/TCPInterface.cpp index 66ca6bc8b..ae4a89a20 100644 --- a/slsDetectorServers/slsDetectorServer/src/TCPInterface.cpp +++ b/slsDetectorServers/slsDetectorServer/src/TCPInterface.cpp @@ -10,25 +10,33 @@ namespace sls { TCPInterface::TCPInterface( std::function &processFunction_, - const uint16_t portNumber) - : processFunction(processFunction_), portNumber(portNumber), - server(portNumber) { - validatePortNumber(portNumber); + const uint16_t portNumber_) + : processFunction(processFunction_), portNumber(portNumber_), + server(portNumber_) { + // validatePortNumber(portNumber); TODO: where to validate? } TCPInterface::~TCPInterface() { - LOG(logINFORED) << "Shutting down TCP Socket on port " << portNumber; + killTcpThread = true; // mmh but if the receiver is stuck in a function, + // this will be of no help + LOG(logINFO) << "Shutting down TCP Socket on port " << portNumber; server.shutdown(); LOG(logDEBUG) << "TCP Socket closed on port " << portNumber; + tcpThread->join(); } void TCPInterface::startTCPServer() { + tcpThread = std::make_unique( + &TCPInterface::startTCPServerClientConnection, this); +} + +void TCPInterface::startTCPServerClientConnection() { LOG(logINFO) << "SLS Server starting TCP Server on port " << portNumber << '\n'; int function_id{}; // TODO should it be an enum type - while (true) { + while (!killTcpThread) { try { auto socket = server.accept(); try {