summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--common/SigUtil.cpp3
-rw-r--r--common/SigUtil.hpp2
-rw-r--r--net/Socket.cpp39
-rw-r--r--net/Socket.hpp39
-rw-r--r--test/Makefile.am3
6 files changed, 70 insertions, 19 deletions
diff --git a/Makefile.am b/Makefile.am
index 315ab91d7f..2b928b1a3b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -54,8 +54,8 @@ shared_sources = common/FileUtil.cpp \
common/Unit.cpp \
common/UnitHTTP.cpp \
common/Util.cpp \
+ net/Socket.cpp \
tools/Replay.hpp
-
if ENABLE_SSL
shared_sources += net/Ssl.cpp
endif
@@ -104,6 +104,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 63d643b051..d88afa46b9 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 a478161f38..21088d666b 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 0000000000..48549db26b
--- /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 026a414028..be19f3ef5e 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 d849f1372e..1785d62c32 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)