[Libreoffice-commits] online.git: Branch 'private/Ashod/nonblocking' - 2 commits - common/SigUtil.cpp common/SigUtil.hpp net/Socket.cpp net/Socket.hpp wsd/LOOLWSD.cpp

Michael Meeks michael.meeks at collabora.com
Fri Mar 3 21:19:42 UTC 2017


 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 <michael.meeks at collabora.com>
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 <michael.meeks at collabora.com>
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.


More information about the Libreoffice-commits mailing list