diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2017-03-02 18:12:52 +0000 |
---|---|---|
committer | Jan Holesovsky <kendy@collabora.com> | 2017-03-10 10:47:42 +0100 |
commit | fa6b75634607591cb41975ccc98d9e2a27869e22 (patch) | |
tree | 150140b8e9d35938eef24cafd4e979cc1c3c3906 | |
parent | nb: No need to construct a new WebSocketHandler here. (diff) | |
download | online-fa6b75634607591cb41975ccc98d9e2a27869e22.tar.gz online-fa6b75634607591cb41975ccc98d9e2a27869e22.zip |
signal handling: keep track of all socket poll wakeups & wakeup.
Instead of waiting for polls to timeout; wake them up.
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | common/SigUtil.cpp | 3 | ||||
-rw-r--r-- | common/SigUtil.hpp | 2 | ||||
-rw-r--r-- | net/Socket.cpp | 39 | ||||
-rw-r--r-- | net/Socket.hpp | 39 | ||||
-rw-r--r-- | test/Makefile.am | 3 |
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) |