[Libreoffice-commits] online.git: loolwsd/DocumentBroker.cpp loolwsd/DocumentBroker.hpp loolwsd/LOOLWSD.cpp
Ashod Nakashian
ashod.nakashian at collabora.co.uk
Mon Nov 7 06:32:28 UTC 2016
loolwsd/DocumentBroker.cpp | 23 +++++++++++++++++++++++
loolwsd/DocumentBroker.hpp | 7 +++++++
loolwsd/LOOLWSD.cpp | 25 ++++++++++++++++++-------
3 files changed, 48 insertions(+), 7 deletions(-)
New commits:
commit 800e711321e19b02f5e15f496525d42edcba4376
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Sat Nov 5 23:00:16 2016 -0400
loolwsd: proper ChildProcess cleanup
Change-Id: If9be827aa50471b7d1d922402414d028ccdcff8b
Reviewed-on: https://gerrit.libreoffice.org/30629
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
diff --git a/loolwsd/DocumentBroker.cpp b/loolwsd/DocumentBroker.cpp
index 19dbb97..507362c 100644
--- a/loolwsd/DocumentBroker.cpp
+++ b/loolwsd/DocumentBroker.cpp
@@ -180,6 +180,10 @@ DocumentBroker::~DocumentBroker()
{
LOG_WRN("DocumentBroker still has unremoved sessions.");
}
+
+ // Need to first make sure the child exited, socket closed,
+ // and thread finished before we are destroyed.
+ _childProcess.reset();
}
bool DocumentBroker::load(const std::string& sessionId, const std::string& jailId)
@@ -922,4 +926,23 @@ void DocumentBroker::childSocketTerminated()
}
}
+void DocumentBroker::terminateChild(std::unique_lock<std::mutex>& lock)
+{
+ Util::assertIsLocked(_mutex);
+ Util::assertIsLocked(lock);
+
+ Log::info() << "Terminating child [" << getPid() << "] of doc [" << _docKey << "]." << Log::end;
+
+ assert(_sessions.empty() && "DocumentBroker still has unremoved sessions!");
+
+ // First flag to stop as it might be waiting on our lock
+ // to process some incoming message.
+ _childProcess->stop();
+
+ // Release the lock and wait for the thread to finish.
+ lock.unlock();
+
+ _childProcess->close(false);
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/loolwsd/DocumentBroker.hpp b/loolwsd/DocumentBroker.hpp
index e58b642..0075fb6 100644
--- a/loolwsd/DocumentBroker.hpp
+++ b/loolwsd/DocumentBroker.hpp
@@ -270,6 +270,13 @@ public:
/// or upon failing to process an incoming message.
void childSocketTerminated();
+ /// This gracefully terminates the connection
+ /// with the child and cleans up ChildProcess etc.
+ /// We must be called under lock and it must be
+ /// passed to us so we unlock before waiting on
+ /// the ChildProcess thread, which can take our lock.
+ void terminateChild(std::unique_lock<std::mutex>& lock);
+
/// Get the PID of the associated child process
Poco::Process::PID getPid() const { return _childProcess->getPid(); }
diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index 7ec35a1..ed5810a 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -565,11 +565,9 @@ private:
if (sessionsCount == 0)
{
// At this point we're done.
- // We can't save if we hadn't, just kill.
- Log::debug("Closing child for docKey [" + docKey + "].");
- child->close(true);
- Log::debug("Removing DocumentBroker for docKey [" + docKey + "].");
+ LOG_DBG("Removing DocumentBroker for docKey [" << docKey << "].");
DocBrokers.erase(docKey);
+ docBroker->terminateChild(docLock);
}
else
{
@@ -928,9 +926,22 @@ private:
if (sessionsCount == 0)
{
- std::unique_lock<std::mutex> DocBrokersLock(DocBrokersMutex);
- Log::debug("Removing DocumentBroker for docKey [" + docKey + "].");
- DocBrokers.erase(docKey);
+ // We've supposedly destroyed the last session and can do away with
+ // DocBroker. But first we need to take both locks in the correct
+ // order and check again. We can't take the DocBrokersMutex while
+ // holding the docBroker lock as that can deadlock with autoSave below.
+ std::unique_lock<std::mutex> docBrokersLock2(DocBrokersMutex);
+ it = DocBrokers.find(docKey);
+ if (it != DocBrokers.end() && it->second)
+ {
+ auto lock = it->second->getLock();
+ if (it->second->getSessionsCount() == 0)
+ {
+ Log::info("Removing DocumentBroker for docKey [" + docKey + "].");
+ DocBrokers.erase(docKey);
+ docBroker->terminateChild(lock);
+ }
+ }
}
LOOLWSD::dumpEventTrace(docBroker->getJailId(), id, "EndSession: " + uri);
More information about the Libreoffice-commits
mailing list