[Libreoffice-commits] online.git: Branch 'private/Ashod/nonblocking' - common/SigUtil.cpp common/SigUtil.hpp Makefile.am net/Socket.cpp net/Socket.hpp test/Makefile.am

Michael Meeks michael.meeks at collabora.com
Thu Mar 2 19:38:59 UTC 2017


 Makefile.am        |    4 +++-
 common/SigUtil.cpp |    3 +++
 common/SigUtil.hpp |    2 ++
 net/Socket.cpp     |   39 +++++++++++++++++++++++++++++++++++++++
 net/Socket.hpp     |   39 ++++++++++++++++++++++-----------------
 test/Makefile.am   |    3 ++-
 6 files changed, 71 insertions(+), 19 deletions(-)

New commits:
commit 9c82365766d5d5ae15b6d3a88647f3945e445eb9
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Thu Mar 2 18:12:52 2017 +0000

    signal handling: keep track of all socket poll wakeups & wakeup.
    
    Instead of waiting for polls to timeout; wake them up.

diff --git a/Makefile.am b/Makefile.am
index 2d8eb16..dd249b7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -59,7 +59,8 @@ shared_sources = common/FileUtil.cpp \
                  common/SpookyV2.cpp \
                  common/Unit.cpp \
                  common/UnitHTTP.cpp \
-                 common/Util.cpp
+                 common/Util.cpp \
+		 net/Socket.cpp
 if ENABLE_SSL
 shared_sources += net/Ssl.cpp
 endif
@@ -105,6 +106,7 @@ loolwsd_fuzzer_SOURCES = $(loolwsd_sources) \
                          kit/DummyLibreOfficeKit.cpp
 
 loolnb_SOURCES = net/loolnb.cpp \
+		 net/Socket.cpp \
                  common/Log.cpp \
                  common/Util.cpp
 if ENABLE_SSL
diff --git a/common/SigUtil.cpp b/common/SigUtil.cpp
index 63d643b..d88afa4 100644
--- a/common/SigUtil.cpp
+++ b/common/SigUtil.cpp
@@ -33,6 +33,7 @@
 #include <string>
 #include <thread>
 
+#include "Socket.hpp"
 #include "Common.hpp"
 #include "Log.hpp"
 #include "Util.hpp"
@@ -119,6 +120,7 @@ namespace SigUtil
             Log::signalLog(signalName(signal));
             Log::signalLog("\n");
             SigUtil::requestShutdown();
+            SocketPoll::wakeupWorld();
         }
         else if (!TerminationFlag)
         {
@@ -127,6 +129,7 @@ namespace SigUtil
             Log::signalLog(signalName(signal));
             Log::signalLog("\n");
             TerminationFlag = true;
+            SocketPoll::wakeupWorld();
         }
         else
         {
diff --git a/common/SigUtil.hpp b/common/SigUtil.hpp
index a478161..21088d6 100644
--- a/common/SigUtil.hpp
+++ b/common/SigUtil.hpp
@@ -25,6 +25,8 @@ namespace SigUtil
     /// Returns the name of the signal.
     const char* signalName(int signo);
 
+    /// Register a wakeup function when changing
+
     /// Trap signals to cleanup and exit the process gracefully.
     void setTerminationSignals();
 
diff --git a/net/Socket.cpp b/net/Socket.cpp
new file mode 100644
index 0000000..48549db
--- /dev/null
+++ b/net/Socket.cpp
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "Socket.hpp"
+
+std::mutex SocketPoll::_pollWakeupsMutex;
+std::vector<int> SocketPoll::_pollWakeups;
+
+SocketPoll::SocketPoll()
+{
+    // Create the wakeup fd.
+    if (::pipe2(_wakeup, O_CLOEXEC | O_NONBLOCK) == -1)
+    {
+        throw std::runtime_error("Failed to allocate pipe for SocketPoll waking.");
+    }
+    std::lock_guard<std::mutex> lock(_pollWakeupsMutex);
+    _pollWakeups.push_back(_wakeup[1]);
+}
+
+SocketPoll::~SocketPoll()
+{
+    ::close(_wakeup[0]);
+    ::close(_wakeup[1]);
+
+    std::lock_guard<std::mutex> lock(_pollWakeupsMutex);
+    auto it = std::find(_pollWakeups.begin(),
+                        _pollWakeups.end(),
+                        _wakeup[1]);
+    if (it != _pollWakeups.end())
+        _pollWakeups.erase(it);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/net/Socket.hpp b/net/Socket.hpp
index 026a414..be19f3e 100644
--- a/net/Socket.hpp
+++ b/net/Socket.hpp
@@ -175,21 +175,13 @@ private:
 /// overhead to adding/removing sockets is not helpful.
 class SocketPoll
 {
-public:
-    SocketPoll()
-    {
-        // Create the wakeup fd.
-        if (::pipe2(_wakeup, O_CLOEXEC | O_NONBLOCK) == -1)
-        {
-            throw std::runtime_error("Failed to allocate pipe for SocketPoll waking.");
-        }
-    }
+    static std::mutex _pollWakeupsMutex;
+    static std::vector<int> _pollWakeups;
 
-    ~SocketPoll()
-    {
-        ::close(_wakeup[0]);
-        ::close(_wakeup[1]);
-    }
+public:
+    /// Create a socket poll, called rather infrequently.
+    SocketPoll();
+    ~SocketPoll();
 
     /// Poll the sockets for available data to read or buffer to write.
     void poll(const int timeoutMaxMs)
@@ -260,18 +252,31 @@ public:
         }
     }
 
-    /// Wakeup the main polling loop in another thread
-    void wakeup()
+    /// Write to a wakeup descriptor
+    static void wakeup (int fd)
     {
         // wakeup the main-loop.
         int rc;
         do {
-            rc = ::write(_wakeup[1], "w", 1);
+            rc = ::write(fd, "w", 1);
         } while (rc == -1 && errno == EINTR);
 
         assert (rc != -1 || errno == EAGAIN || errno == EWOULDBLOCK);
     }
 
+    /// Wakeup the main polling loop in another thread
+    void wakeup()
+    {
+        wakeup(_wakeup[1]);
+    }
+
+    /// Global wakeup - signal safe: wakeup all socket polls.
+    static void wakeupWorld()
+    {
+        for (const auto& fd : _pollWakeups)
+            wakeup(fd);
+    }
+
     /// Insert a new socket to be polled.
     /// Sockets are removed only when the handler return false.
     void insertNewSocket(const std::shared_ptr<Socket>& newSocket)
diff --git a/test/Makefile.am b/test/Makefile.am
index d849f13..1785d62 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -39,7 +39,8 @@ wsd_sources = \
             ../kit/Kit.cpp \
             ../wsd/TileCache.cpp \
             ../common/Unit.cpp \
-            ../common/Util.cpp
+            ../common/Util.cpp \
+            ../net/Socket.cpp
 
 unittest_CPPFLAGS = -I$(top_srcdir) -DBUILDING_TESTS
 unittest_SOURCES = TileQueueTests.cpp WhiteBoxTests.cpp test.cpp $(wsd_sources)


More information about the Libreoffice-commits mailing list