common/SigUtil.cpp | 27 +++++++++++++++++++++++++++ common/SigUtil.hpp | 6 ++++++ net/Socket.cpp | 45 ++++++++++++++++++++++++++++++++++++--------- net/Socket.hpp | 21 +++++++++++++-------- wsd/LOOLWSD.cpp | 31 +++++++++++++++++++++++++++++-- 5 files changed, 111 insertions(+), 19 deletions(-)
New commits: commit b41d38925e298e3d78ae5cd0d05f62ea01a10e56 Author: Michael Meeks <[email protected]> Date: Fri Mar 3 21:18:55 2017 +0000 Connect USR1 to initial global state dumping goodness. diff --git a/common/SigUtil.cpp b/common/SigUtil.cpp index d88afa4..0be2b70 100644 --- a/common/SigUtil.cpp +++ b/common/SigUtil.cpp @@ -39,6 +39,7 @@ #include "Util.hpp" std::atomic<bool> TerminationFlag(false); +std::atomic<bool> DumpGlobalState(false); std::mutex SigHandlerTrap; /// Flag to shutdown the server. @@ -247,6 +248,32 @@ namespace SigUtil strncpy(FatalGdbString, streamStr.c_str(), sizeof(FatalGdbString)); } + static + void handleUserSignal(const int signal) + { + Log::signalLogPrefix(); + Log::signalLog(" User signal received: "); + Log::signalLog(signalName(signal)); + Log::signalLog("\n"); + if (signal == SIGUSR1) + { + DumpGlobalState = true; + SocketPoll::wakeupWorld(); + } + } + + void setUserSignals() + { + struct sigaction action; + + sigemptyset(&action.sa_mask); + action.sa_flags = 0; + action.sa_handler = handleUserSignal; + + sigaction(SIGUSR1, &action, nullptr); + } + + void requestShutdown() { ShutdownRequestFlag = true; diff --git a/common/SigUtil.hpp b/common/SigUtil.hpp index 21088d6..9dabcfc 100644 --- a/common/SigUtil.hpp +++ b/common/SigUtil.hpp @@ -16,6 +16,9 @@ /// Flag to stop pump loops. extern std::atomic<bool> TerminationFlag; +/// Flag to dump internal state +extern std::atomic<bool> DumpGlobalState; + /// Mutex to trap signal handler, if any, /// and prevent _Exit while collecting backtrace. extern std::mutex SigHandlerTrap; @@ -33,6 +36,9 @@ namespace SigUtil /// Trap all fatal signals to assist debugging. void setFatalSignals(); + /// Trap generally useful signals + void setUserSignals(); + /// Requests the server to initiate graceful shutdown. /// Shutting down is a multi-stage process, because /// it can be requested via signals. diff --git a/net/Socket.cpp b/net/Socket.cpp index 4865737..31cbc1d 100644 --- a/net/Socket.cpp +++ b/net/Socket.cpp @@ -54,4 +54,13 @@ void SocketPoll::wakeupWorld() wakeup(fd); } +void SocketPoll::dumpState() +{ + std::cerr << " Poll [" << _pollSockets.size() << "] - wakeup r: " + << _wakeup[0] << " w: " << _wakeup[1] << "\n"; + std::cerr << "\tfd\tevents\trsize\twsize\n"; + for (auto &i : _pollSockets) + i->dumpState(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/net/Socket.hpp b/net/Socket.hpp index c7d58fd..ab077dc 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -148,6 +148,8 @@ public: return rc; } + virtual void dumpState() {} + protected: /// Construct based on an existing socket fd. @@ -292,6 +294,8 @@ public: wakeup(); } + void dumpState(); + private: void removeSocketFromPoll(const std::shared_ptr<Socket>& socket) @@ -551,6 +555,14 @@ protected: return ::write(getFD(), buf, len); } + void dumpState() override + { + std::cerr << "\t" << getFD() << "\t" << getPollEvents() << "\t" + << _inBuffer.size() << "\t" << _outBuffer.size() << "\t" + << "\n"; + // FIXME: hex dump buffer contents if we have them. + } + /// Get the Write Lock. std::unique_lock<std::mutex> getWriteLock() { return std::unique_lock<std::mutex>(_writeMutex); } diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp index 9c50e25..4ae5516 100644 --- a/wsd/LOOLWSD.cpp +++ b/wsd/LOOLWSD.cpp @@ -197,6 +197,8 @@ static std::mutex DocBrokersMutex; static std::vector<std::shared_ptr<LOOLWebSocket> > ClientWebSockets; static std::mutex ClientWebSocketsMutex; +extern "C" { void dump_state(void); /* easy for gdb */ } + #if ENABLE_DEBUG static int careerSpanSeconds = 0; #endif @@ -3322,7 +3324,6 @@ class LOOLWSDServer { LOOLWSDServer(LOOLWSDServer&& other) = delete; const LOOLWSDServer& operator=(LOOLWSDServer&& other) = delete; - public: LOOLWSDServer() : _stop(false) @@ -3369,6 +3370,20 @@ public: _stop = true; } + void dumpState() + { + std::cerr << "LOOLWSDServer:\n" + << " stop: " << _stop << "\n" + << " TerminationFlag: " << TerminationFlag << "\n" + << " isShuttingDown: " << SigUtil::isShuttingDown() << "\n"; + + std::cerr << "Server poll:\n"; + _serverPoll.dumpState(); + + std::cerr << "Document poll:\n"; + _documentPoll.dumpState(); + } + private: std::atomic<bool> _stop; @@ -3383,6 +3398,11 @@ private: LOG_INF("Starting master server thread."); while (!stop && !TerminationFlag && !SigUtil::isShuttingDown()) { + if (DumpGlobalState) + { + dump_state(); + DumpGlobalState = false; + } serverPoll.poll(30000); } } @@ -3396,9 +3416,12 @@ private: } }; +LOOLWSDServer srv; + int LOOLWSD::main(const std::vector<std::string>& /*args*/) { #ifndef FUZZER + SigUtil::setUserSignals(); SigUtil::setFatalSignals(); SigUtil::setTerminationSignals(); #endif @@ -3533,7 +3556,6 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/) srv.start(); #endif - LOOLWSDServer srv; // TODO loolnb SocketAddress addr("127.0.0.1", ClientPortNumber); srv.start(addr); @@ -3741,6 +3763,11 @@ void alertAllUsers(const std::string& msg) } #endif +void dump_state() +{ + srv.dumpState(); +} + POCO_SERVER_MAIN(LOOLWSD) /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 5bacf6e2e2f9e82643cfc4f82cdbce93574dc218 Author: Michael Meeks <[email protected]> Date: Fri Mar 3 21:18:27 2017 +0000 Work around global initialization order issue with global wakeups. diff --git a/net/Socket.cpp b/net/Socket.cpp index 48549db..4865737 100644 --- a/net/Socket.cpp +++ b/net/Socket.cpp @@ -9,8 +9,19 @@ #include "Socket.hpp" -std::mutex SocketPoll::_pollWakeupsMutex; -std::vector<int> SocketPoll::_pollWakeups; +// help with initialization order +namespace { + std::vector<int> &getWakeupsArray() + { + static std::vector<int> pollWakeups; + return pollWakeups; + } + std::mutex &getPollWakeupsMutex() + { + static std::mutex pollWakeupsMutex; + return pollWakeupsMutex; + } +} SocketPoll::SocketPoll() { @@ -19,8 +30,8 @@ SocketPoll::SocketPoll() { throw std::runtime_error("Failed to allocate pipe for SocketPoll waking."); } - std::lock_guard<std::mutex> lock(_pollWakeupsMutex); - _pollWakeups.push_back(_wakeup[1]); + std::lock_guard<std::mutex> lock(getPollWakeupsMutex()); + getWakeupsArray().push_back(_wakeup[1]); } SocketPoll::~SocketPoll() @@ -28,12 +39,19 @@ SocketPoll::~SocketPoll() ::close(_wakeup[0]); ::close(_wakeup[1]); - std::lock_guard<std::mutex> lock(_pollWakeupsMutex); - auto it = std::find(_pollWakeups.begin(), - _pollWakeups.end(), + std::lock_guard<std::mutex> lock(getPollWakeupsMutex()); + auto it = std::find(getWakeupsArray().begin(), + getWakeupsArray().end(), _wakeup[1]); - if (it != _pollWakeups.end()) - _pollWakeups.erase(it); + + if (it != getWakeupsArray().end()) + getWakeupsArray().erase(it); +} + +void SocketPoll::wakeupWorld() +{ + for (const auto& fd : getWakeupsArray()) + wakeup(fd); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/net/Socket.hpp b/net/Socket.hpp index be19f3e..c7d58fd 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -175,9 +175,6 @@ private: /// overhead to adding/removing sockets is not helpful. class SocketPoll { - static std::mutex _pollWakeupsMutex; - static std::vector<int> _pollWakeups; - public: /// Create a socket poll, called rather infrequently. SocketPoll(); @@ -271,11 +268,7 @@ public: } /// Global wakeup - signal safe: wakeup all socket polls. - static void wakeupWorld() - { - for (const auto& fd : _pollWakeups) - wakeup(fd); - } + static void wakeupWorld(); /// Insert a new socket to be polled. /// Sockets are removed only when the handler return false. _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
