[Libreoffice-commits] online.git: wsd/LOOLWSD.cpp

Ashod Nakashian ashod.nakashian at collabora.co.uk
Tue Jan 3 05:57:50 UTC 2017


 wsd/LOOLWSD.cpp |   38 +++++++++++++++++++++++++++++++-------
 1 file changed, 31 insertions(+), 7 deletions(-)

New commits:
commit 1cf7a6bca12de6a88357f0367b28c20b1078e348
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Mon Jan 2 21:59:32 2017 -0500

    wsd: cleanup DocBroker after exceptions
    
    Change-Id: I6a07845506afd5eae482da5d4367eb397846f410
    Reviewed-on: https://gerrit.libreoffice.org/32674
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>

diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index 3725e95..cd176da 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -982,7 +982,7 @@ private:
                 throw WebSocketErrorMessageException(SERVICE_UNAVAILABLE_INTERNAL_ERROR);
             }
 
-            // Set one we just created.
+            // Set the one we just created.
             LOG_DBG("New DocumentBroker for docKey [" << docKey << "].");
             docBroker = std::make_shared<DocumentBroker>(uriPublic, docKey, LOOLWSD::ChildRoot, child);
             child->setDocumentBroker(docBroker);
@@ -1019,7 +1019,7 @@ private:
         // Below this, we need to cleanup internal references.
         try
         {
-            // Now the bridge beetween the client and kit process is connected
+            // Now the bridge between the client and kit process is connected
             const std::string statusReady = "statusindicator: ready";
             LOG_TRC("Sending to Client [" << statusReady << "].");
             ws->sendFrame(statusReady.data(), statusReady.size());
@@ -1031,12 +1031,30 @@ private:
                 Util::alertAllUsers("error: cmd=internal kind=diskfull");
             }
 
+            LOOLWSD::dumpEventTrace(docBroker->getJailId(), id, "NewSession: " + uri);
+
             // Request the child to connect to us and add this session.
-            auto sessionsCount = docBroker->addSession(session);
+            const auto sessionsCount = docBroker->addSession(session);
             LOG_TRC(docKey << ", ws_sessions++: " << sessionsCount);
+        }
+        catch (const std::exception& exc)
+        {
+            LOG_WRN("Exception while preparing session [" << id << "].");
 
-            LOOLWSD::dumpEventTrace(docBroker->getJailId(), id, "NewSession: " + uri);
+            std::unique_lock<std::mutex> docBrokersLock(DocBrokersMutex);
+            auto lock = docBroker->getLock();
+            if (docBroker->getSessionsCount() == 0 || !docBroker->isAlive())
+            {
+                LOG_INF("Removing unloaded DocumentBroker for docKey [" << docKey << "].");
+                DocBrokers.erase(docKey);
+                docBroker->terminateChild(lock);
+            }
 
+            return;
+        }
+
+        try
+        {
             // Let messages flow.
             IoUtil::SocketProcessor(ws, "client_ws_" + id,
                 [&session](const std::vector<char>& payload)
@@ -1058,7 +1076,7 @@ private:
                 // We issue a force-save when last editable (non-readonly) session is going away
                 const bool forceSave = docBroker->startDestroy(id);
 
-                sessionsCount = docBroker->getSessionsCount();
+                auto sessionsCount = docBroker->getSessionsCount();
                 if (sessionsCount > 1)
                 {
                     sessionsCount = docBroker->removeSession(id);
@@ -1092,8 +1110,14 @@ private:
                 // 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);
-                cleanupDocBrokers();
+                std::unique_lock<std::mutex> docBrokersLock(DocBrokersMutex);
+                auto lock = docBroker->getLock();
+                if (docBroker->getSessionsCount() == 0 || !docBroker->isAlive())
+                {
+                    LOG_INF("Removing unloaded DocumentBroker for docKey [" << docKey << "].");
+                    DocBrokers.erase(docKey);
+                    docBroker->terminateChild(lock);
+                }
             }
 
             if (SigUtil::isShuttingDown())


More information about the Libreoffice-commits mailing list