[Libreoffice-commits] online.git: loolwsd/ChildProcessSession.cpp loolwsd/MasterProcessSession.cpp loolwsd/test

Michael Meeks michael.meeks at collabora.com
Wed Apr 20 10:26:39 UTC 2016


 loolwsd/ChildProcessSession.cpp  |   47 +++++++++++++++++++++++++++------------
 loolwsd/MasterProcessSession.cpp |   46 +++++++++++++++++++++++++++++++-------
 loolwsd/test/run_unit.sh.in      |    2 -
 3 files changed, 72 insertions(+), 23 deletions(-)

New commits:
commit a47355db2f2b04617ba85d1540d0523f1830640f
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Tue Apr 19 21:50:43 2016 +0100

    Expand use of the TileBeingRendered structure.
    
    Implement this for tilecombine, and do tile writes in each client's
    thread separately. Add env-var. to trigger sleep, and tune it to 1
    second; easily long enough to exercise this code-path.

diff --git a/loolwsd/ChildProcessSession.cpp b/loolwsd/ChildProcessSession.cpp
index 18bdfb6..408ecac 100644
--- a/loolwsd/ChildProcessSession.cpp
+++ b/loolwsd/ChildProcessSession.cpp
@@ -639,6 +639,32 @@ bool ChildProcessSession::getPartPageRectangles(const char* /*buffer*/, int /*le
     return true;
 }
 
+namespace {
+    inline bool delayAndRewritePart(int &part)
+    {
+#if ENABLE_DEBUG
+        static bool delayEnv = getenv("DELAY_TILES");
+        if (delayEnv)
+            return true;
+
+        if (part == 42)
+        {
+            part = 0;
+            return true;
+        }
+#endif
+        return false;
+    }
+    inline void delay()
+    {
+#if ENABLE_DEBUG
+        Log::debug("Sleeping for one second");
+        std::this_thread::sleep_for(std::chrono::seconds(1));
+#endif
+    }
+}
+
+
 void ChildProcessSession::sendTile(const char* /*buffer*/, int /*length*/, StringTokenizer& tokens)
 {
     int part, width, height, tilePosX, tilePosY, tileWidth, tileHeight;
@@ -683,14 +709,7 @@ void ChildProcessSession::sendTile(const char* /*buffer*/, int /*length*/, Strin
     std::vector<unsigned char> pixmap;
     pixmap.resize(4 * width * height);
 
-#if ENABLE_DEBUG
-    bool makeSlow = false;
-    if (part == 42)
-    {
-        makeSlow = true;
-        part = 0;
-    }
-#endif
+    bool makeSlow = delayAndRewritePart(part);
 
     if (_docType != "text" && part != _loKitDocument->pClass->getPart(_loKitDocument))
     {
@@ -710,13 +729,8 @@ void ChildProcessSession::sendTile(const char* /*buffer*/, int /*length*/, Strin
         return;
     }
 
-#if ENABLE_DEBUG
     if (makeSlow)
-    {
-        Log::debug("Sleeping for 5 seconds");
-        std::this_thread::sleep_for(std::chrono::seconds(5));
-    }
-#endif
+        delay();
 
     sendBinaryFrame(output.data(), output.size());
 }
@@ -751,6 +765,8 @@ void ChildProcessSession::sendCombinedTiles(const char* /*buffer*/, int /*length
     if (tokens.count() > 8)
         getTokenString(tokens[8], "timestamp", reqTimestamp);
 
+    bool makeSlow = delayAndRewritePart(part);
+
     Util::Rectangle renderArea;
 
     StringTokenizer positionXtokens(tilePositionsX, ",", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
@@ -855,6 +871,9 @@ void ChildProcessSession::sendCombinedTiles(const char* /*buffer*/, int /*length
 
         sendBinaryFrame(output.data(), output.size());
     }
+
+    if (makeSlow)
+        delay();
 }
 
 bool ChildProcessSession::clientZoom(const char* /*buffer*/, int /*length*/, StringTokenizer& tokens)
diff --git a/loolwsd/MasterProcessSession.cpp b/loolwsd/MasterProcessSession.cpp
index 8e433d1..54962b9 100644
--- a/loolwsd/MasterProcessSession.cpp
+++ b/loolwsd/MasterProcessSession.cpp
@@ -179,6 +179,7 @@ bool MasterProcessSession::_handleInput(const char *buffer, int length)
                     !getTokenInteger(tokens[7], "tileheight", tileHeight))
                     assert(false);
 
+                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();
@@ -190,8 +191,18 @@ bool MasterProcessSession::_handleInput(const char *buffer, int length)
                         auto subscriber = i.lock();
                         if (subscriber)
                         {
-                            Log::debug("Sending tile also to subscriber " + subscriber->getName());
-                            subscriber->sendBinaryFrame(buffer, length);
+                            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
+                            // to re-check and hit the cache. NB. it needs to be
+                            // 'tile' and not 'tile'
+                            if (queue)
+                            {
+                                std::string noColon = firstLine + "\n";
+                                noColon.erase(4,1);
+                                queue->put(noColon);
+                            }
                         }
                     }
                     _docBroker->tileCache().forgetTileBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight);
@@ -590,6 +601,7 @@ void MasterProcessSession::sendTile(const char *buffer, int length, StringTokeni
     if (tileBeingRendered)
     {
         Log::debug("Tile is already being rendered, subscribing");
+        assert(_kind == Kind::ToClient);
         tileBeingRendered->subscribe(shared_from_this());
         return;
     }
@@ -698,13 +710,31 @@ void MasterProcessSession::sendCombinedTiles(const char* /*buffer*/, int /*lengt
         }
         else
         {
-            if (!forwardTileX.empty())
-                forwardTileX += ",";
-            forwardTileX += std::to_string(x);
+            // 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 (!forwardTileY.empty())
-                forwardTileY += ",";
-            forwardTileY += std::to_string(y);
+            if (!subscribed)
+            {
+                if (!forwardTileX.empty())
+                    forwardTileX += ",";
+                forwardTileX += std::to_string(x);
+
+                if (!forwardTileY.empty())
+                    forwardTileY += ",";
+                forwardTileY += std::to_string(y);
+            }
         }
     }
 
diff --git a/loolwsd/test/run_unit.sh.in b/loolwsd/test/run_unit.sh.in
index acfac8e..b6305d2 100755
--- a/loolwsd/test/run_unit.sh.in
+++ b/loolwsd/test/run_unit.sh.in
@@ -77,7 +77,7 @@ else # newer unit tests.
                                    --lotemplate="$lo_path" \
                                    --childroot="$jails_path" \
                                    --allowlocalstorage \
-                                   --admincreds=admin/admin \
+                                   --admincreds="admin/admin" \
                                    --unitlib=".libs/$tst.so" 2> "$tst_log"; then
         echo "Test $tst passed."
         echo ":test-result: PASS $tst" >> $test_output


More information about the Libreoffice-commits mailing list