From 3b9014922986e270f7fde9910603b13de198bf5d Mon Sep 17 00:00:00 2001 From: Ashod Nakashian Date: Sat, 19 Nov 2016 10:22:53 -0500 Subject: [PATCH] loolwsd: notify clients of shutdown Change-Id: I8dbe5752e8e36e2a1f6dee05f5f355f5a7b4d1b6 Reviewed-on: https://gerrit.libreoffice.org/31001 Reviewed-by: Ashod Nakashian Tested-by: Ashod Nakashian --- loolwsd/Admin.cpp | 2 +- loolwsd/DocumentBroker.cpp | 1 + loolwsd/LOOLWSD.cpp | 3 +-- loolwsd/common/SigUtil.cpp | 22 +++++++++++++++++++++- loolwsd/common/SigUtil.hpp | 15 +++++++++++++++ 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/loolwsd/Admin.cpp b/loolwsd/Admin.cpp index d24c52426..c9bd23b50 100644 --- a/loolwsd/Admin.cpp +++ b/loolwsd/Admin.cpp @@ -149,7 +149,7 @@ bool AdminRequestHandler::adminCommandHandler(const std::vector& payload) else if (tokens[0] == "shutdown") { LOG_INF("Shutdown requested by admin."); - ShutdownFlag = true; + SigUtil::requestShutdown(); return false; } else if (tokens[0] == "set" && tokens.count() > 1) diff --git a/loolwsd/DocumentBroker.cpp b/loolwsd/DocumentBroker.cpp index 9e4cc3d6a..52f60c78b 100644 --- a/loolwsd/DocumentBroker.cpp +++ b/loolwsd/DocumentBroker.cpp @@ -582,6 +582,7 @@ void DocumentBroker::alertAllUsers(const std::string& msg) { Util::assertIsLocked(_mutex); + LOG_DBG("Alerting all users: " << msg); for (auto& it : _sessions) { try diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp index 0a345919b..2cdf5d471 100644 --- a/loolwsd/LOOLWSD.cpp +++ b/loolwsd/LOOLWSD.cpp @@ -1971,7 +1971,7 @@ int LOOLWSD::main(const std::vector& /*args*/) while (!TerminationFlag && !ShutdownFlag) { UnitWSD::get().invokeTest(); - if (TerminationFlag) + if (TerminationFlag || SigUtil::handleShutdownRequest()) { break; } @@ -2078,7 +2078,6 @@ int LOOLWSD::main(const std::vector& /*args*/) // and wait until sockets close. LOG_INF("Stopping server socket listening. ShutdownFlag: " << ShutdownFlag << ", TerminationFlag: " << TerminationFlag); - Util::alertAllUsers("close: shutdown"); srv.stop(); srv2.stop(); diff --git a/loolwsd/common/SigUtil.cpp b/loolwsd/common/SigUtil.cpp index 8d884bffb..db29de598 100644 --- a/loolwsd/common/SigUtil.cpp +++ b/loolwsd/common/SigUtil.cpp @@ -54,6 +54,8 @@ std::atomic TerminationFlag(false); std::atomic ShutdownFlag(false); std::mutex SigHandlerTrap; +static std::atomic ShutdownRequestFlag(false); + namespace SigUtil { const char *signalName(const int signo) @@ -125,7 +127,7 @@ namespace SigUtil Log::signalLog(" Shutdown signal received: "); Log::signalLog(signalName(signal)); Log::signalLog("\n"); - ShutdownFlag = true; + SigUtil::requestShutdown(); } else { @@ -242,6 +244,24 @@ namespace SigUtil strncpy(FatalGdbString, streamStr.c_str(), sizeof(FatalGdbString)); } + void requestShutdown() + { + ShutdownRequestFlag = true; + } + + bool handleShutdownRequest() + { + if (ShutdownRequestFlag) + { + LOG_INF("Shutdown requested. Initiating WSD shutdown."); + Util::alertAllUsers("close: shutdown"); + ShutdownFlag = true; + return true; + } + + return false; + } + bool killChild(const int pid) { LOG_DBG("Killing PID: " << pid); diff --git a/loolwsd/common/SigUtil.hpp b/loolwsd/common/SigUtil.hpp index e1221b34d..1d1b0f11d 100644 --- a/loolwsd/common/SigUtil.hpp +++ b/loolwsd/common/SigUtil.hpp @@ -37,6 +37,21 @@ namespace SigUtil /// Trap all fatal signals to assist debugging. void setFatalSignals(); + /// Requests the server to initiate graceful shutdown. + /// Shutting down is a multi-stage process, because + /// it can be requested via signals. + /// Since we need to notify clients, we can't + /// invoke the sockets while in a signal handler. + /// This flags the server to notify clients first + /// then flags for shutdown. + void requestShutdown(); + + /// Checks for shutdown request and, + /// after notifying clients, flags for + /// shutting down. + /// Returns true if shutdown is requested. + bool handleShutdownRequest(); + /// Kills a child process and returns true when /// child pid is removed from the process table /// after a certain (short) timeout.