[Libreoffice-commits] online.git: loolwsd/Admin.cpp loolwsd/Admin.hpp loolwsd/AdminModel.cpp loolwsd/AdminModel.hpp loolwsd/LOOLWSD.cpp

Ashod Nakashian ashod.nakashian at collabora.co.uk
Mon Apr 18 03:35:47 UTC 2016


 loolwsd/Admin.cpp      |    6 ++++++
 loolwsd/Admin.hpp      |    3 +++
 loolwsd/AdminModel.cpp |   20 ++++++++++++++++++++
 loolwsd/AdminModel.hpp |    3 +++
 loolwsd/LOOLWSD.cpp    |    2 ++
 5 files changed, 34 insertions(+)

New commits:
commit 892358e5cb662b14c7168878d58d83ac76fb58c1
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sun Apr 17 22:32:58 2016 -0400

    loolwsd: new Admin API to remove documents
    
    Normally, when each client view closes, the
    session count is decremented until the last
    view is closed. However this doesn't work
    when the kit child process terminates.
    
    Due to a race condition between the last
    client disconnecting, and the internal
    structure destructing, and the next
    client connecting (on the same doc),
    the Admin loses track of the doc and pid.
    
    This is an issue of assuming a document
    and its pid are unique and will always
    remain unchanged.
    
    This patch adds a new API to remove a
    doc and all its views unconditionally
    to try to avoid the above issues.
    
    Change-Id: I0c181260679875b0464dd9b6548b29b8d6a361f7
    Reviewed-on: https://gerrit.libreoffice.org/24183
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>

diff --git a/loolwsd/Admin.cpp b/loolwsd/Admin.cpp
index 951acb3..dcd9ad4 100644
--- a/loolwsd/Admin.cpp
+++ b/loolwsd/Admin.cpp
@@ -397,6 +397,12 @@ void Admin::rmDoc(const std::string& docKey, const std::string& sessionId)
     _model.removeDocument(docKey, sessionId);
 }
 
+void Admin::rmDoc(const std::string& docKey)
+{
+    std::unique_lock<std::mutex> modelLock(_modelMutex);
+    _model.removeDocument(docKey);
+}
+
 void MemoryStats::run()
 {
     std::unique_lock<std::mutex> modelLock(_admin->getLock());
diff --git a/loolwsd/Admin.hpp b/loolwsd/Admin.hpp
index e4d3aca..3e66b17 100644
--- a/loolwsd/Admin.hpp
+++ b/loolwsd/Admin.hpp
@@ -59,6 +59,9 @@ public:
     /// Decrement view count till becomes zero after which doc is removed
     void rmDoc(const std::string& docKey, const std::string& sessionId);
 
+    /// Remove the document with all views. Used on termination or catastrophic failure.
+    void rmDoc(const std::string& docKey);
+
     void setForKitPid(const int forKitPid) { _forKitPid = forKitPid; }
 
     /// Callers must ensure that modelMutex is acquired
diff --git a/loolwsd/AdminModel.cpp b/loolwsd/AdminModel.cpp
index 4bba2d7..ccc342f 100644
--- a/loolwsd/AdminModel.cpp
+++ b/loolwsd/AdminModel.cpp
@@ -284,6 +284,26 @@ void AdminModel::removeDocument(const std::string& docKey, const std::string& se
     }
 }
 
+void AdminModel::removeDocument(const std::string& docKey)
+{
+    auto docIt = _documents.find(docKey);
+    if (docIt != _documents.end())
+    {
+        for (const auto& pair : docIt->second.getViews())
+        {
+            // Notify the subscribers
+            std::ostringstream oss;
+            oss << "rmdoc "
+                << docIt->second.getPid() << " "
+                << pair.first;
+            Log::info("Message to admin console: " + oss.str());
+            notify(oss.str());
+        }
+
+        _documents.erase(docIt);
+    }
+}
+
 std::string AdminModel::getMemStats()
 {
     std::string response;
diff --git a/loolwsd/AdminModel.hpp b/loolwsd/AdminModel.hpp
index 0ce5931..3707598 100644
--- a/loolwsd/AdminModel.hpp
+++ b/loolwsd/AdminModel.hpp
@@ -68,6 +68,8 @@ public:
 
     unsigned getActiveViews() const { return _activeViews; }
 
+    const std::map<std::string, View>& getViews() const { return _views; }
+
 private:
     const std::string _docKey;
     const Poco::Process::PID _pid;
@@ -160,6 +162,7 @@ public:
     void addDocument(const std::string& docKey, Poco::Process::PID pid, const std::string& filename, const std::string& sessionId);
 
     void removeDocument(const std::string& docKey, const std::string& sessionId);
+    void removeDocument(const std::string& docKey);
 
 private:
 
diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index 34b031e..7f833fb 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -586,6 +586,8 @@ private:
         {
             Log::debug("Removing DocumentBroker for docKey [" + docKey + "].");
             docBrokers.erase(docKey);
+            Log::info("Removing complete doc [" + docKey + "] from Admin.");
+            Admin::instance().rmDoc(docKey);
         }
     }
 


More information about the Libreoffice-commits mailing list