From f2d84739cf0cf170e62823a377c6381acff2ab3c Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Thu, 26 May 2016 15:26:38 +0100 Subject: [PATCH] Rewrite signal handling. Fixes a lock up. --- command.cc | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++---- command.h | 11 ++++++++++- main.cc | 49 +++------------------------------------------- 3 files changed, 66 insertions(+), 51 deletions(-) diff --git a/command.cc b/command.cc index 121c11f..7a2b11f 100644 --- a/command.cc +++ b/command.cc @@ -57,7 +57,6 @@ #include "vsleeptimer.h" #include "wjpeg.h" - Command* Command::instance = NULL; Command::Command() @@ -67,6 +66,7 @@ Command::Command() initted = 0; isStandby = 0; firstBoot = 1; + signals = 0; connLost = NULL; crashed = false; server = NULL; @@ -238,10 +238,10 @@ void Command::run() #else ReleaseMutex(masterLock); #endif - - button = remote->getButtonPress(2); // FIXME why is this set to 2 and not 0? so it can quit + button = remote->getButtonPress(2); // Don't block (0) in case a signal arrives after checking signals but before this line // something happened, lock and process - + if (signals) processSignals(); // If a signal arrived process now. + // logger->log("Command", Log::DEBUG, "WANT LOCK"); #ifndef WIN32 pthread_mutex_lock(&masterLock); @@ -267,6 +267,55 @@ void Command::run() } +void Command::setSignal(int signalReceived) +{ + if (signalReceived == SIGINT) + signals |= SIG_INT; + else if (signalReceived == SIGTERM) + signals |= SIG_TERM; + else if (signalReceived == SIGUSR1) + signals |= SIG_USR1; + else if (signalReceived == SIGUSR2) + signals |= SIG_USR2; + else if (signalReceived == SIGURG) + signals |= SIG_URG; +} + +void Command::processSignals() +{ + if (signals & SIG_INT) + { + signals = signals & ~SIG_INT; + logger->log("Command", Log::NOTICE, "INT signal, shutting down..."); + stop(); + } + + if (signals & SIG_TERM) + { + signals = signals & ~SIG_TERM; + logger->log("Command", Log::NOTICE, "TERM signal, shutting down..."); + stop(); + } + + if (signals & SIG_USR1) + { + logger->log("Command", Log::NOTICE, "USR1 signal"); + signals = signals & ~SIG_USR1; + } + + if (signals & SIG_USR2) + { + logger->log("Command", Log::NOTICE, "USR2 signal"); + signals = signals & ~SIG_USR2; + } + + if (signals & SIG_URG) + { + logger->log("Command", Log::NOTICE, "URG signal"); // This is used to break from getButtonPress to process the message queue + signals = signals & ~SIG_URG; + } +} + void Command::postMessage(Message* m) { // This is locked here in case the main loop is not waiting for an event, but is processing one diff --git a/command.h b/command.h index 443f043..b00671e 100644 --- a/command.h +++ b/command.h @@ -57,6 +57,12 @@ struct ASLPref { typedef vector ASLPrefList; +#define SIG_INT 1 +#define SIG_TERM 2 +#define SIG_USR1 4 +#define SIG_USR2 8 +#define SIG_URG 16 + class Command : public MessageQueue { public: @@ -73,7 +79,7 @@ class Command : public MessageQueue void postMessageNoLock(Message* m); // override of MessageQueue::postMessage bool postMessageIfNotBusy(Message* m); // for timers, when masterMutex might be locked void postMessageFromOuterSpace(Message* m); // err, read the cc comments. - void sig1(); + void setSignal(int signalReceived); void connectionLost(); void setAdvMenues(bool adv) {advmenues=adv;}; @@ -85,6 +91,7 @@ class Command : public MessageQueue private: void handleCommand(int); + void processSignals(); void doStandby(); void doPowerOn(); void doPowerOff(); @@ -92,6 +99,7 @@ class Command : public MessageQueue void doWallpaper(); void doFromTheTop(bool which); // true - show vinfo,wait. false - del vinfo,restart void buildCrashedBox(); + void sig1(); static Command* instance; #ifndef WIN32 @@ -105,6 +113,7 @@ class Command : public MessageQueue UCHAR irun; UCHAR isStandby; UCHAR firstBoot; + ULONG signals; Log* logger; BoxStack* boxstack; diff --git a/main.cc b/main.cc index d412558..46aa498 100644 --- a/main.cc +++ b/main.cc @@ -93,8 +93,6 @@ void sighandler(int signalReceived); void shutdown(int code); - - // Global variables -------------------------------------------------------------------------------------------------- Log* logger; Remote* remote; @@ -237,14 +235,12 @@ int main(int argc, char** argv) logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGUSR1. Aborting."); shutdown(1); } -/* sigtest = signal(SIGUSR2, sighandler); if (sigtest == SIG_ERR) { logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGUSR2. Aborting."); shutdown(1); } -*/ sigtest = signal(SIGURG, sighandler); if (sigtest == SIG_ERR) { @@ -411,49 +407,9 @@ int main(int argc, char** argv) void sighandler(int signalReceived) { - logger->log("Core", Log::NOTICE, "Signal %i received", signalReceived); - - switch (signalReceived) - { - case SIGINT: - { - logger->log("Core", Log::NOTICE, "Interrupt signal, shutting down..."); - command->stop(); // FIXME this is probably not safe - use the messaging system / is that even safe? - break; - } - case SIGTERM: - { - logger->log("Core", Log::NOTICE, "Term signal, shutting down..."); - command->stop(); // FIXME this is probably not safe - use the messaging system / is that even safe? - break; - } - case SIGUSR1: - { - logger->log("Core", Log::NOTICE, "USR1 signal, screenshot..."); - command->sig1(); - break; - } -/* - case SIGUSR1: - { - logger->log("Core", Log::DEBUG, "SIGUSR1 caught"); - logger->upLogLevel(); - break; - } - case SIGUSR2: - { - logger->log("Core", Log::DEBUG, "SIGUSR2 caught"); - logger->downLogLevel(); - break; - } -*/ - case SIGURG: - { - logger->log("Core", Log::DEBUG, "SIGURG caught"); - break; - } - } + if (command) command->setSignal(signalReceived); } + #endif // ------------------------------------------------------------------------------------------------------------------- @@ -472,6 +428,7 @@ void shutdown(int code) { command->shutdown(); delete command; + command = NULL; logger->log("Core", Log::NOTICE, "Command module shut down"); } -- 2.39.2