[Libreoffice-commits] online.git: loolwsd/DocumentBroker.hpp loolwsd/LOOLWSD.cpp
Ashod Nakashian
ashod.nakashian at collabora.co.uk
Sun Apr 24 17:00:37 UTC 2016
loolwsd/DocumentBroker.hpp | 21 +++++++++++++++++++
loolwsd/LOOLWSD.cpp | 48 ++++++++++++++++++++++++++++++---------------
2 files changed, 53 insertions(+), 16 deletions(-)
New commits:
commit 2b5ecbd945b2d46cc9c7e0bead6e8304e5c31f21
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Sun Apr 24 11:56:02 2016 -0400
loolwsd: validate child and spawn new ones before using
Change-Id: Icf7c8a2c0fa6c455cea4a65207f1727638169a28
Reviewed-on: https://gerrit.libreoffice.org/24335
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
diff --git a/loolwsd/DocumentBroker.hpp b/loolwsd/DocumentBroker.hpp
index 9129fec..dcf2d2a 100644
--- a/loolwsd/DocumentBroker.hpp
+++ b/loolwsd/DocumentBroker.hpp
@@ -20,6 +20,7 @@
#include <map>
#include <Poco/URI.h>
+#include <Poco/Net/WebSocket.h>
#include "IoUtil.hpp"
#include "MasterProcessSession.hpp"
@@ -95,6 +96,25 @@ public:
Poco::Process::PID getPid() const { return _pid; }
std::shared_ptr<Poco::Net::WebSocket> getWebSocket() const { return _ws; }
+ /// Check whether this child is alive and able to respond.
+ bool isAlive() const
+ {
+ try
+ {
+ if (_pid > 1 && _ws && kill(_pid, 0) == 0)
+ {
+ // We don't care about the response (and shouldn't read here).
+ _ws->sendFrame("PING", 4, Poco::Net::WebSocket::FRAME_OP_PING);
+ return true;
+ }
+ }
+ catch (const std::exception& exc)
+ {
+ }
+
+ return false;
+ }
+
private:
Poco::Process::PID _pid;
std::shared_ptr<Poco::Net::WebSocket> _ws;
@@ -152,6 +172,7 @@ public:
const std::string& getDocKey() const { return _docKey; }
const std::string& getFilename() const { return _filename; };
TileCache& tileCache() { return *_tileCache; }
+ bool isAlive() const { return _childProcess && _childProcess->isAlive(); }
size_t getSessionsCount() const
{
std::lock_guard<std::mutex> lock(_mutex);
diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index a0e46ef..ea40a49 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -190,27 +190,43 @@ static std::shared_ptr<ChildProcess> getNewChild()
{
std::unique_lock<std::mutex> lock(newChildrenMutex);
- const int available = newChildren.size();
- int balance = LOOLWSD::NumPreSpawnedChildren;
- if (available == 0)
+ namespace chrono = std::chrono;
+ const auto startTime = chrono::steady_clock::now();
+ do
{
- Log::error("No available child. Sending spawn request to forkit and failing.");
- }
- else
- {
- balance -= available - 1;
- }
+ const int available = newChildren.size();
+ int balance = LOOLWSD::NumPreSpawnedChildren;
+ if (available == 0)
+ {
+ Log::error("getNewChild: No available child. Sending spawn request to forkit and failing.");
+ }
+ else
+ {
+ balance -= available - 1; // Minus the one we'll dispatch just now.
+ }
- forkChildren(balance);
+ Log::debug("getNewChild: Have " + std::to_string(available) + " children, forking " + std::to_string(balance));
+ forkChildren(balance);
- const auto timeout = std::chrono::milliseconds(CHILD_TIMEOUT_SECS * 1000);
- if (newChildrenCV.wait_for(lock, timeout, [](){ return !newChildren.empty(); }))
- {
- auto child = newChildren.back();
- newChildren.pop_back();
- return child;
+ const auto timeout = chrono::milliseconds(CHILD_TIMEOUT_SECS * 1000);
+ if (newChildrenCV.wait_for(lock, timeout, [](){ return !newChildren.empty(); }))
+ {
+ auto child = newChildren.back();
+ newChildren.pop_back();
+
+ // Validate before returning.
+ if (child && child->isAlive())
+ {
+ Log::debug("getNewChild: Returning new child [" + std::to_string(child->getPid()) + "].");
+ return child;
+ }
+
+ Log::debug("getNewChild: No live child, forking more.");
+ }
}
+ while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - startTime).count() < CHILD_TIMEOUT_SECS * 2000);
+ Log::debug("getNewChild: Timed out while waiting for new child.");
return nullptr;
}
More information about the Libreoffice-commits
mailing list