[Libreoffice-commits] online.git: net/Socket.hpp wsd/DocumentBroker.cpp wsd/DocumentBroker.hpp wsd/LOOLWSD.cpp
net/Socket.hpp |3 + wsd/DocumentBroker.cpp | 75 + wsd/DocumentBroker.hpp |3 - wsd/LOOLWSD.cpp| 25 +++- 4 files changed, 78 insertions(+), 28 deletions(-) New commits: commit 9b3a22aafee8d0163212ea0c1b499eb03cb632ba Author: Ashod Nakashian Date: Wed Apr 19 00:54:42 2017 -0400 wsd: save document upon server shutdown The server correctly saves all documents and waits to upload them before exiting. Change-Id: I04dc9ce588bc0fa39a9deb298d0a5efa61a03f1a Reviewed-on: https://gerrit.libreoffice.org/36654 Reviewed-by: Ashod Nakashian Tested-by: Ashod Nakashian diff --git a/net/Socket.hpp b/net/Socket.hpp index 89844912..c0b4b97e 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -438,7 +438,8 @@ public: void wakeup() { if (!isAlive()) -LOG_WRN("Waking up dead poll thread [" << _name << "]"); +LOG_WRN("Waking up dead poll thread [" << _name << "], started: " << +_threadStarted << ", finished: " << _threadFinished); wakeup(_wakeup[1]); } diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp index 8ad9571e..94a49a1d 100644 --- a/wsd/DocumentBroker.cpp +++ b/wsd/DocumentBroker.cpp @@ -12,6 +12,7 @@ #include "DocumentBroker.hpp" #include +#include #include #include #include @@ -220,29 +221,66 @@ void DocumentBroker::pollThread() auto last30SecCheckTime = std::chrono::steady_clock::now(); +static const bool AutoSaveEnabled = !std::getenv("LOOL_NO_AUTOSAVE"); + // Main polling loop goodness. -while (!_stop && _poll->continuePolling() && !TerminationFlag && !ShutdownRequestFlag) +while (!_stop && _poll->continuePolling() && !TerminationFlag) { _poll->poll(SocketPoll::DefaultPollTimeoutMs); -if (!std::getenv("LOOL_NO_AUTOSAVE") && !_stop && -std::chrono::duration_cast -(std::chrono::steady_clock::now() - last30SecCheckTime).count() >= 30) +const auto now = std::chrono::steady_clock::now(); +if (_lastSaveTime < _lastSaveRequestTime && +std::chrono::duration_cast +(now - _lastSaveRequestTime).count() <= COMMAND_TIMEOUT_MS) +{ +// We are saving, nothing more to do but wait. +continue; +} + +if (ShutdownRequestFlag) { -LOG_TRC("Trigger an autosave ..."); +// Shutting down the server: notify clients, save, and stop. +static const std::string msg("close: recycling"); + +// First copy into local container, since removeSession +// will erase from _sessions, but will leave the last. +std::vector> sessions; +for (const auto& pair : _sessions) +{ +sessions.push_back(pair.second); +} + +for (const std::shared_ptr& session : sessions) +{ +try +{ +// Notify the client and disconnect. +session->sendMessage(msg); + session->shutdown(WebSocketHandler::StatusCodes::ENDPOINT_GOING_AWAY, "recycling"); + +// Remove session, save, and mark to destroy. +removeSession(session->getId(), true); +} +catch (const std::exception& exc) +{ +LOG_WRN("Error while shutting down client [" << +session->getName() << "]: " << exc.what()); +} +} +} +else if (AutoSaveEnabled && !_stop && + std::chrono::duration_cast(now - last30SecCheckTime).count() >= 30) +{ +LOG_TRC("Triggering an autosave."); autoSave(false); last30SecCheckTime = std::chrono::steady_clock::now(); } -const bool notSaving = (std::chrono::duration_cast -(std::chrono::steady_clock::now() - _lastSaveRequestTime).count() > COMMAND_TIMEOUT_MS); - // Remove idle documents after 1 hour. const bool idle = (getIdleTimeSecs() >= 3600); // If all sessions have been removed, no reason to linger. -if ((isLoaded() || _markToDestroy) && notSaving && -(_sessions.empty() || idle)) +if ((isLoaded() || _markToDestroy) && (_sessions.empty() || idle)) { LOG_INF("Terminating " << (idle ? "idle" : "dead") << " DocumentBroker for docKey [" << getDocKey() << "]."); @@ -251,17 +289,8 @@ void DocumentBroker::pollThread() } LOG_INF("Finished polling doc [" << _docKey << "]. stop: " << _stop << ", continuePolling: " << -_poll->continuePolling() << ", TerminationFlag: " << TerminationFlag << -", ShutdownRequestFlag: " << ShutdownRequestFlag << "."); -
[Libreoffice-commits] online.git: net/Socket.hpp wsd/DocumentBroker.cpp wsd/DocumentBroker.hpp wsd/LOOLWSD.cpp
net/Socket.hpp |3 --- wsd/DocumentBroker.cpp |5 - wsd/DocumentBroker.hpp |3 --- wsd/LOOLWSD.cpp|4 ++-- 4 files changed, 2 insertions(+), 13 deletions(-) New commits: commit 3d945a5c3846d662e878a5daace5554704e0e586 Author: Michael Meeks Date: Thu Apr 6 16:35:55 2017 +0100 Revert "Don't cleanup DocumentBrokers that still have their thread running." This reverts commit df8dc43be4980302d4287c0692d02cf4fe6ca253. DocumentBroker::isAlive already checks _threadFinished. diff --git a/net/Socket.hpp b/net/Socket.hpp index 42238751..c726f337 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -500,9 +500,6 @@ public: /// Stop and join the polling thread before returning (if active) void joinThread(); -/// Did our thread complete its execution -bool isThreadFinished() { return _threadFinished; } - private: /// Initialize the poll fds array with the right events void setupPollFds(std::chrono::steady_clock::time_point now, diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp index 9515fbb4..a5a995df 100644 --- a/wsd/DocumentBroker.cpp +++ b/wsd/DocumentBroker.cpp @@ -305,11 +305,6 @@ DocumentBroker::~DocumentBroker() _childProcess.reset(); } -bool DocumentBroker::isThreadFinished() -{ -return _poll->isThreadFinished(); -} - void DocumentBroker::joinThread() { _poll->joinThread(); diff --git a/wsd/DocumentBroker.hpp b/wsd/DocumentBroker.hpp index 11d50174..d05437e9 100644 --- a/wsd/DocumentBroker.hpp +++ b/wsd/DocumentBroker.hpp @@ -227,9 +227,6 @@ public: /// Thread safe termination of this broker if it has a lingering thread void joinThread(); -/// Is our polling thread safely out of the way -bool isThreadFinished(); - /// Loads a document from the public URI into the jail. bool load(const std::shared_ptr& session, const std::string& jailId); bool isLoaded() const { return _isLoaded; } diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp index 1c446462..e5d4cb68 100644 --- a/wsd/LOOLWSD.cpp +++ b/wsd/LOOLWSD.cpp @@ -250,8 +250,8 @@ void cleanupDocBrokers() " DocumentBroker for docKey [" << it->first << "]."); docBroker->stop(); -// Remove only on next pass when the thread is finished. -if (docBroker->isThreadFinished() && !docBroker->isAlive()) +// Remove only when not alive. +if (!docBroker->isAlive()) { LOG_INF("Removing " << (idle ? "idle" : "dead") << " DocumentBroker for docKey [" << it->first << "]."); ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] online.git: net/Socket.hpp wsd/DocumentBroker.cpp wsd/DocumentBroker.hpp wsd/LOOLWSD.cpp
net/Socket.hpp |3 +++ wsd/DocumentBroker.cpp |5 + wsd/DocumentBroker.hpp |3 +++ wsd/LOOLWSD.cpp|4 ++-- 4 files changed, 13 insertions(+), 2 deletions(-) New commits: commit df8dc43be4980302d4287c0692d02cf4fe6ca253 Author: Michael Meeks Date: Wed Apr 5 21:48:51 2017 +0100 Don't cleanup DocumentBrokers that still have their thread running. Plenty of time to do that next time around the cleanup. We should still, really be doing the majority of the timeout work inside the DocumentBroker poll itself. diff --git a/net/Socket.hpp b/net/Socket.hpp index c726f337..42238751 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -500,6 +500,9 @@ public: /// Stop and join the polling thread before returning (if active) void joinThread(); +/// Did our thread complete its execution +bool isThreadFinished() { return _threadFinished; } + private: /// Initialize the poll fds array with the right events void setupPollFds(std::chrono::steady_clock::time_point now, diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp index a5a995df..9515fbb4 100644 --- a/wsd/DocumentBroker.cpp +++ b/wsd/DocumentBroker.cpp @@ -305,6 +305,11 @@ DocumentBroker::~DocumentBroker() _childProcess.reset(); } +bool DocumentBroker::isThreadFinished() +{ +return _poll->isThreadFinished(); +} + void DocumentBroker::joinThread() { _poll->joinThread(); diff --git a/wsd/DocumentBroker.hpp b/wsd/DocumentBroker.hpp index d05437e9..11d50174 100644 --- a/wsd/DocumentBroker.hpp +++ b/wsd/DocumentBroker.hpp @@ -227,6 +227,9 @@ public: /// Thread safe termination of this broker if it has a lingering thread void joinThread(); +/// Is our polling thread safely out of the way +bool isThreadFinished(); + /// Loads a document from the public URI into the jail. bool load(const std::shared_ptr& session, const std::string& jailId); bool isLoaded() const { return _isLoaded; } diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp index e5d4cb68..1c446462 100644 --- a/wsd/LOOLWSD.cpp +++ b/wsd/LOOLWSD.cpp @@ -250,8 +250,8 @@ void cleanupDocBrokers() " DocumentBroker for docKey [" << it->first << "]."); docBroker->stop(); -// Remove only when not alive. -if (!docBroker->isAlive()) +// Remove only on next pass when the thread is finished. +if (docBroker->isThreadFinished() && !docBroker->isAlive()) { LOG_INF("Removing " << (idle ? "idle" : "dead") << " DocumentBroker for docKey [" << it->first << "]."); ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] online.git: net/Socket.hpp wsd/DocumentBroker.cpp wsd/DocumentBroker.hpp wsd/LOOLWSD.cpp
net/Socket.hpp |1 - wsd/DocumentBroker.cpp |5 + wsd/DocumentBroker.hpp |8 wsd/LOOLWSD.cpp|6 +- 4 files changed, 14 insertions(+), 6 deletions(-) New commits: commit 97e9463f173c833ce9d4b0503ea865ebd70a7a33 Author: Michael Meeks Date: Mon Mar 13 12:00:31 2017 + Revert "wsd: TerminatingPoll always starts its own thread" This reverts commit 388d7b1dbf1a5c2d155c0149247b3a319114f8b0. It is vital to have clean control of thread start. By starting a thread during init. of a member (or base-clase) we loose lots of control, some examples: Any members initialized after a member that auto-starts a thread, is effectively un-defined, and cannot be accessed reliably. This is particularly problematic for sub-classes. I've seen threads started before the base-class has finished constructing in the original creating thread - such that the vtable was not yet updated to the sub-class causing the transient parent vtable used during construction to be used in-error. diff --git a/net/Socket.hpp b/net/Socket.hpp index 5cced5f..16c0cdc 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -435,7 +435,6 @@ public: const std::string& name() const { return _name; } -protected: /// Start the polling thread (if desired) void startThread(); diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp index a53a7c1..04fe5ac 100644 --- a/wsd/DocumentBroker.cpp +++ b/wsd/DocumentBroker.cpp @@ -162,6 +162,11 @@ DocumentBroker::DocumentBroker(const std::string& uri, LOG_INF("DocumentBroker [" << _uriPublic.toString() << "] created. DocKey: [" << _docKey << "]"); } +void DocumentBroker::startThread() +{ +_poll->startThread(); +} + // The inner heart of the DocumentBroker - our poll loop. void DocumentBroker::pollThread() { diff --git a/wsd/DocumentBroker.hpp b/wsd/DocumentBroker.hpp index 8d7eb2a..8d36cb2 100644 --- a/wsd/DocumentBroker.hpp +++ b/wsd/DocumentBroker.hpp @@ -44,10 +44,7 @@ class TerminatingPoll : public SocketPoll { public: TerminatingPoll(const std::string &threadName) : -SocketPoll(threadName) -{ -startThread(); -} +SocketPoll(threadName) {} bool continuePolling() override { @@ -221,6 +218,9 @@ public: ~DocumentBroker(); +/// Start processing events +void startThread(); + /// Loads a document from the public URI into the jail. bool load(std::shared_ptr& session, const std::string& jailId); bool isLoaded() const { return _isLoaded; } diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp index 97cf845..b4d42ab 100644 --- a/wsd/LOOLWSD.cpp +++ b/wsd/LOOLWSD.cpp @@ -2177,6 +2177,7 @@ private: void handleClientWsUpgrade(const Poco::Net::HTTPRequest& request, const std::string& url) { +// requestHandler = new ClientRequestHandler(); LOG_INF("Client WS request" << request.getURI() << ", url: " << url); // First Upgrade. @@ -2230,9 +2231,9 @@ private: _clientSession->onConnect(socket); docBroker->addSocketToPoll(socket); } +docBroker->startThread(); } } - if (!docBroker || !_clientSession) LOG_WRN("Failed to connect DocBroker and Client Session."); } @@ -2358,11 +2359,14 @@ public: void startPrisoners(const int port) { PrisonerPoll.insertNewSocket(findPrisonerServerPort(port)); +PrisonerPoll.startThread(); } void start(const int port) { _acceptPoll.insertNewSocket(findServerPort(port)); +_acceptPoll.startThread(); +WebServerPoll.startThread(); } void stop() ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits