[Libreoffice-commits] online.git: loolwsd/ChildSession.hpp loolwsd/LOOLKit.cpp

Ashod Nakashian ashod.nakashian at collabora.co.uk
Mon Aug 15 03:07:17 UTC 2016


 loolwsd/ChildSession.hpp |    2 -
 loolwsd/LOOLKit.cpp      |   77 +++++++++++++++++++++--------------------------
 2 files changed, 36 insertions(+), 43 deletions(-)

New commits:
commit ae5f47234ccc88c87d886ffa86eec422bf5043d8
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Fri Aug 12 21:15:38 2016 -0400

    loolwsd: per-session callbacks
    
    Callbacks from Core are now per-session and not
    shared among all. A new descriptor is used to
    help get from the callback to the respective
    session.
    
    Change-Id: Ie72771da05eef4760cf01351f7c06c034abf5109
    Reviewed-on: https://gerrit.libreoffice.org/28122
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>

diff --git a/loolwsd/ChildSession.hpp b/loolwsd/ChildSession.hpp
index 15a2e18..7045a04 100644
--- a/loolwsd/ChildSession.hpp
+++ b/loolwsd/ChildSession.hpp
@@ -44,7 +44,7 @@ public:
     bool getPartPageRectangles(const char *buffer, int length);
     virtual void disconnect() override;
 
-    int getViewId() const { return _viewId; }
+    unsigned getViewId() const { return _viewId; }
 
     const std::string& getDocType() const { return _docType; }
 
diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp
index 50f100a..74d259c 100644
--- a/loolwsd/LOOLKit.cpp
+++ b/loolwsd/LOOLKit.cpp
@@ -342,6 +342,14 @@ private:
 /// Regex to parse the ViewId from json.
 static std::regex ViewIdRegex("\"viewId\"\\s*:\\s*\"(\\d*)\"");
 
+class Document;
+
+struct CallbackDescriptor
+{
+    const Document* const Doc;
+    const unsigned ViewId;
+};
+
 /// A document container.
 /// Owns LOKitDocument instance and connections.
 /// Manages the lifetime of a document.
@@ -727,49 +735,22 @@ private:
         Log::trace() << "Document::ViewCallback "
                      << LOKitHelper::kitCallbackTypeToString(nType)
                      << " [" << payload << "]." << Log::end;
-        Document* self = reinterpret_cast<Document*>(pData);
-        if (self == nullptr)
-        {
-            return;
-        }
+        CallbackDescriptor* pDescr = reinterpret_cast<CallbackDescriptor*>(pData);
+        assert(pDescr && "Null callback data.");
+        assert(pDescr->Doc && "Null Document instance.");
 
-        std::unique_lock<std::mutex> lock(self->_mutex);
-
-        if (nType == LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY ||
-            nType == LOK_CALLBACK_DOCUMENT_PASSWORD)
-        {
-            // Mark the document password type.
-            self->setDocumentPassword(nType);
-            return;
-        }
-
-        // We can't invoke loKitDocument here as that could deadlock.
-        // We have to parse the message to get the target view.
-        // We can do it here once at the expense of the lok thread, or,
-        // dispatch swiftly and prase multiple times in each session.
-        int viewId = -1;
-        std::smatch match;
-        if (std::regex_search(payload.begin(), payload.end(), match, ViewIdRegex) &&
-            match.length() > 1)
-        {
-            const auto strViewId = match[1].str();
-            viewId = std::stoi(strViewId);
-        }
+        std::unique_lock<std::mutex> lock(pDescr->Doc->_mutex);
 
         // Forward to the same view only.
-        for (auto& it: self->_connections)
+        // Demultiplexing is done by Core.
+        // TODO: replace with a map to be faster.
+        for (auto& it: pDescr->Doc->_connections)
         {
-            if (it.second->isRunning())
+            auto session = it.second->getSession();
+            if (session && it.second->isRunning() &&
+                session->getViewId() == pDescr->ViewId)
             {
-                auto session = it.second->getSession();
-                if (session)
-                {
-                    if (viewId < 0 || session->getViewId() == viewId)
-                    {
-                        // Broadcast if not view-specific.
-                        session->loKitCallback(nType, payload);
-                    }
-                }
+                session->loKitCallback(nType, payload);
             }
         }
     }
@@ -879,6 +860,7 @@ private:
                         << _clientViews << " views." << Log::end;
 
             const auto viewId = _loKitDocument->getView();
+            _viewIdToCallbackDescr.erase(viewId);
             _loKitDocument->registerCallback(nullptr, nullptr);
             _loKitDocument->destroyView(viewId);
         }
@@ -901,7 +883,7 @@ private:
         }
 
         auto session = it->second->getSession();
-        auto& callback = _multiView ? ViewCallback : DocumentCallback;
+        unsigned viewId = 0;
 
         if (!_loKitDocument)
         {
@@ -986,7 +968,7 @@ private:
             if (_multiView)
             {
                 Log::info("Loading view to document from URI: [" + uri + "] for session [" + sessionId + "].");
-                const auto viewId = _loKitDocument->createView();
+                viewId = _loKitDocument->createView();
 
                 Log::info() << "Document [" << _url << "] view ["
                             << viewId << "] loaded, leaving "
@@ -998,7 +980,17 @@ private:
         // registerCallback(), as the previous creates a new view in Impress.
         _loKitDocument->initializeForRendering(_renderOpts.c_str());
 
-        _loKitDocument->registerCallback(callback, this);
+        if (_multiView)
+        {
+            _viewIdToCallbackDescr.emplace(viewId,
+                std::unique_ptr<CallbackDescriptor>(new CallbackDescriptor({ this, viewId })));
+
+            _loKitDocument->registerCallback(ViewCallback, _viewIdToCallbackDescr[viewId].get());
+        }
+        else
+        {
+            _loKitDocument->registerCallback(DocumentCallback, this);
+        }
 
         return _loKitDocument;
     }
@@ -1024,9 +1016,10 @@ private:
     // Whether password is required to view the document, or modify it
     PasswordType _docPasswordType;
 
-    std::mutex _mutex;
+    mutable std::mutex _mutex;
     std::condition_variable _cvLoading;
     std::atomic_size_t _isLoading;
+    std::map<unsigned, std::unique_ptr<CallbackDescriptor>> _viewIdToCallbackDescr;
     std::map<unsigned, std::shared_ptr<Connection>> _connections;
     std::atomic_size_t _clientViews;
 };


More information about the Libreoffice-commits mailing list