[Libreoffice-commits] online.git: 2 commits - loolwsd/LOOLSession.hpp loolwsd/MasterProcessSession.cpp loolwsd/TileCache.cpp loolwsd/TileCache.hpp

Michael Meeks michael.meeks at collabora.com
Sat Apr 23 17:04:11 UTC 2016


 loolwsd/LOOLSession.hpp          |    2 
 loolwsd/MasterProcessSession.cpp |   73 +++---------------------------------
 loolwsd/TileCache.cpp            |   79 ++++++++++++++++++++++++++++++++++-----
 loolwsd/TileCache.hpp            |   13 ++++--
 4 files changed, 89 insertions(+), 78 deletions(-)

New commits:
commit 8f7eed639cdb358354b5157d7f2c5b0e2202cafd
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Sat Apr 23 17:11:11 2016 +0100

    Re-factor tile subscription logic.
    
    Move the logic into the TileCache, simplify the API, and
    internalize the lock. This should be a plain re-factor.

diff --git a/loolwsd/LOOLSession.hpp b/loolwsd/LOOLSession.hpp
index 86d398d..95d1fc8 100644
--- a/loolwsd/LOOLSession.hpp
+++ b/loolwsd/LOOLSession.hpp
@@ -68,6 +68,8 @@ public:
     void closeFrame() { _isCloseFrame = true; };
     bool isCloseFrame() const { return _isCloseFrame; }
 
+    Kind getKind() const { return _kind; }
+
 protected:
     LOOLSession(const std::string& id, const Kind kind,
                 std::shared_ptr<Poco::Net::WebSocket> ws);
diff --git a/loolwsd/MasterProcessSession.cpp b/loolwsd/MasterProcessSession.cpp
index cae00ce..58e1910 100644
--- a/loolwsd/MasterProcessSession.cpp
+++ b/loolwsd/MasterProcessSession.cpp
@@ -195,45 +195,8 @@ bool MasterProcessSession::_handleInput(const char *buffer, int length)
                 assert(_kind == Kind::ToPrisoner);
                 assert(firstLine.size() < static_cast<std::string::size_type>(length));
                 _docBroker->tileCache().saveTile(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight, buffer + firstLine.size() + 1, length - firstLine.size() - 1);
-                auto lock = _docBroker->tileCache().getTilesBeingRenderedLock();
-                std::shared_ptr<TileBeingRendered> tileBeingRendered = _docBroker->tileCache().findTileBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight);
-                if (tileBeingRendered)
-                {
-                    for (auto i: tileBeingRendered->getSubscribers())
-                    {
-                        auto subscriber = i.lock();
-                        if (subscriber)
-                        {
-                            if (subscriber.get() == this)
-                            {
-                                Log::debug("Refusing to queue new tile message for ourselves");
-                                continue;
-                            }
-
-                            Log::debug("Sending tile message also to subscriber " + subscriber->getName() + " line: '" + firstLine + "'");
-                            std::shared_ptr<BasicTileQueue> queue;
-                            queue = subscriber->getQueue();
-                            // Re-emit the tile command in the other thread(s) to re-check and hit
-                            // the cache. Construct the message from scratch to contain only the
-                            // mandatory parts of the message.
-                            if (queue)
-                            {
-                                const std::string message("tile "
-                                                          " part=" + std::to_string(part) +
-                                                          " width=" + std::to_string(width) +
-                                                          " height=" + std::to_string(height) +
-                                                          " tileposx=" + std::to_string(tilePosX) +
-                                                          " tileposy=" + std::to_string(tilePosY) +
-                                                          " tilewidth=" + std::to_string(tileWidth) +
-                                                          " tileheight=" + std::to_string(tileHeight) +
-                                                          "\n");
-                                queue->put(message);
-                            }
-                        }
-                    }
-                    _docBroker->tileCache().forgetTileBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight);
-                }
-                lock.unlock();
+
+                _docBroker->tileCache().notifyAndRemoveSubscribers(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight, this);
             }
             else if (tokens[0] == "status:")
             {
@@ -595,17 +558,10 @@ void MasterProcessSession::sendTile(const char *buffer, int length, StringTokeni
         return;
     }
 
-    auto lock = _docBroker->tileCache().getTilesBeingRenderedLock();
-    std::shared_ptr<TileBeingRendered> tileBeingRendered = _docBroker->tileCache().findTileBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight);
-    if (tileBeingRendered)
-    {
-        Log::debug("Tile is already being rendered, subscribing");
-        assert(_kind == Kind::ToClient);
-        tileBeingRendered->subscribe(shared_from_this());
+    if (_docBroker->tileCache().isTileBeingRenderedIfSoSubscribe(
+            part, width, height, tilePosX, tilePosY, tileWidth,
+            tileHeight, shared_from_this()))
         return;
-    }
-    _docBroker->tileCache().rememberTileAsBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight);
-    lock.unlock();
 
     if (_peer.expired())
         dispatchChild();
@@ -713,22 +669,9 @@ void MasterProcessSession::sendCombinedTiles(const char* /*buffer*/, int /*lengt
         }
         else
         {
-            // FIXME: rip out into a helper method [!?] ...
-            auto lock = _docBroker->tileCache().getTilesBeingRenderedLock();
-            std::shared_ptr<TileBeingRendered> tileBeingRendered = _docBroker->tileCache().findTileBeingRendered(part, pixelWidth, pixelHeight, x, y, tileWidth, tileHeight);
-            bool subscribed = false;
-            if (tileBeingRendered)
-            {
-                Log::debug("Tile (combined) is already being rendered, subscribing");
-                assert(_kind == Kind::ToClient);
-                tileBeingRendered->subscribe(shared_from_this());
-                subscribed = true;
-            }
-            else
-                _docBroker->tileCache().rememberTileAsBeingRendered(part, pixelWidth, pixelHeight, x, y, tileWidth, tileHeight);
-            lock.unlock();
-
-            if (!subscribed)
+            if (!_docBroker->tileCache().isTileBeingRenderedIfSoSubscribe(
+                    part, pixelWidth, pixelHeight, x, y, tileWidth,
+                    tileHeight, shared_from_this()))
             {
                 if (!forwardTileX.empty())
                     forwardTileX += ",";
diff --git a/loolwsd/TileCache.cpp b/loolwsd/TileCache.cpp
index 033eb44..383bb87 100644
--- a/loolwsd/TileCache.cpp
+++ b/loolwsd/TileCache.cpp
@@ -33,6 +33,7 @@
 #include "LOOLProtocol.hpp"
 #include "TileCache.hpp"
 #include "Util.hpp"
+#include "MasterProcessSession.hpp"
 
 using Poco::DirectoryIterator;
 using Poco::File;
@@ -93,15 +94,6 @@ TileCache::TileCache(const std::string& docURL,
 TileCache::~TileCache()
 {
     Log::info("~TileCache dtor for uri [" + _docURL + "].");
-#if 0
-    auto lock = getTilesBeingRenderedLock();
-    _tilesBeingRendered.clear();
-#endif
-}
-
-std::unique_lock<std::mutex> TileCache::getTilesBeingRenderedLock()
-{
-    return std::unique_lock<std::mutex>(_tilesBeingRenderedMutex);
 }
 
 void TileCache::rememberTileAsBeingRendered(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight)
@@ -357,4 +349,68 @@ void TileCache::saveLastModified(const Timestamp& timestamp)
     modTimeFile.close();
 }
 
+void TileCache::notifyAndRemoveSubscribers(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, MasterProcessSession *emitter)
+{
+    std::unique_lock<std::mutex> lock(_tilesBeingRenderedMutex);
+
+    std::shared_ptr<TileBeingRendered> tileBeingRendered = findTileBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight);
+    if (!tileBeingRendered)
+        return;
+
+    Log::debug("Sending tile message also to subscribers");
+
+    for (auto i: tileBeingRendered->getSubscribers())
+    {
+        auto subscriber = i.lock();
+        if (subscriber)
+        {
+            if (subscriber.get() == emitter)
+            {
+                Log::error("Refusing to queue new tile message for ourselves");
+                continue;
+            }
+
+            std::shared_ptr<BasicTileQueue> queue;
+            queue = subscriber->getQueue();
+            // Re-emit the tile command in the other thread(s) to re-check and hit
+            // the cache. Construct the message from scratch to contain only the
+            // mandatory parts of the message.
+            if (queue)
+            {
+                const std::string message("tile "
+                                          " part=" + std::to_string(part) +
+                                          " width=" + std::to_string(width) +
+                                          " height=" + std::to_string(height) +
+                                          " tileposx=" + std::to_string(tilePosX) +
+                                          " tileposy=" + std::to_string(tilePosY) +
+                                          " tilewidth=" + std::to_string(tileWidth) +
+                                          " tileheight=" + std::to_string(tileHeight) +
+                                          "\n");
+                queue->put(message);
+            }
+        }
+    }
+    forgetTileBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight);
+
+    lock.unlock();
+}
+
+bool TileCache::isTileBeingRenderedIfSoSubscribe(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, const std::shared_ptr<MasterProcessSession> &subscriber)
+{
+    std::unique_lock<std::mutex> lock(_tilesBeingRenderedMutex);
+
+    std::shared_ptr<TileBeingRendered> tileBeingRendered = findTileBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight);
+    if (tileBeingRendered)
+    {
+        Log::debug("Tile is already being rendered, subscribing");
+        assert(subscriber->getKind() == LOOLSession::Kind::ToClient);
+        tileBeingRendered->subscribe(subscriber);
+        return true;
+    }
+    rememberTileAsBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight);
+    lock.unlock();
+
+    return false;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/loolwsd/TileCache.hpp b/loolwsd/TileCache.hpp
index f4911b4..f52533d 100644
--- a/loolwsd/TileCache.hpp
+++ b/loolwsd/TileCache.hpp
@@ -44,17 +44,21 @@ public:
 
     TileCache(const TileCache&) = delete;
 
-    std::unique_lock<std::mutex> getTilesBeingRenderedLock();
-
     void rememberTileAsBeingRendered(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight);
 
-    std::shared_ptr<TileBeingRendered> findTileBeingRendered(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight);
+    std::shared_ptr<TileBeingRendered> findTileBeingRendered(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight)
+;
+
+    bool isTileBeingRenderedIfSoSubscribe(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, const std::shared_ptr<MasterProcessSession> &subscriber);
 
     void forgetTileBeingRendered(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight);
 
     std::unique_ptr<std::fstream> lookupTile(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight);
 
     void saveTile(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, const char *data, size_t size);
+
+    void notifyAndRemoveSubscribers(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, MasterProcessSession *emitter);
+
     std::string getTextFile(const std::string& fileName);
 
     // Save some text into a file in the cache directory
commit 2c2504a07341a55f565ddae80a758a02b0776447
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Sat Apr 23 16:53:03 2016 +0100

    Time stamp subscriptions to tile rendering.

diff --git a/loolwsd/TileCache.cpp b/loolwsd/TileCache.cpp
index 6fbdc63..033eb44 100644
--- a/loolwsd/TileCache.cpp
+++ b/loolwsd/TileCache.cpp
@@ -44,6 +44,11 @@ using Poco::URI;
 
 using namespace LOOLProtocol;
 
+TileBeingRendered::TileBeingRendered()
+{
+    _startTime.update();
+}
+
 void TileBeingRendered::subscribe(const std::weak_ptr<MasterProcessSession>& session)
 {
     std::shared_ptr<MasterProcessSession> cmp = session.lock();
diff --git a/loolwsd/TileCache.hpp b/loolwsd/TileCache.hpp
index 7c6c279..f4911b4 100644
--- a/loolwsd/TileCache.hpp
+++ b/loolwsd/TileCache.hpp
@@ -25,9 +25,10 @@ class MasterProcessSession;
 
 class TileBeingRendered
 {
+    Poco::Timestamp _startTime;
     std::vector<std::weak_ptr<MasterProcessSession>> _subscribers;
-
 public:
+    TileBeingRendered();
     void subscribe(const std::weak_ptr<MasterProcessSession>& session);
     std::vector<std::weak_ptr<MasterProcessSession>> getSubscribers();
 };


More information about the Libreoffice-commits mailing list