loolwsd/LOOLWSD.cpp              |   32 +++++++++++---------------------
 loolwsd/MasterProcessSession.cpp |    3 ++-
 loolwsd/MessageQueue.hpp         |    6 +++++-
 loolwsd/QueueHandler.hpp         |    8 +++++---
 4 files changed, 23 insertions(+), 26 deletions(-)

New commits:
commit 3217b4592a6e196486440c2149132233b79d5982
Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk>
Date:   Sat Mar 26 22:56:10 2016 -0400

    loolwsd: queue payload changed to vector<char>
    
    All messages now pass through the queue.
    This resolves a race between single-line
    messages and multi-line ones.
    
    Previously, single-line messages were
    processed on the queue (on a background
    thread) while multi-line ones were handled
    immediatly. This resulted in order-inversion
    due to a race between the queue thread and the
    next multi-line message, which caused stability
    issues every so often.
    
    Change-Id: Ia220791d1d75c4f3e3e0965dd0c6f81bae63a296
    Reviewed-on: https://gerrit.libreoffice.org/23583
    Reviewed-by: Ashod Nakashian <ashnak...@gmail.com>
    Tested-by: Ashod Nakashian <ashnak...@gmail.com>

diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index 749b2e2..b4cc910 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -221,7 +221,7 @@ public:
 // Handler returns false to end.
 void SocketProcessor(std::shared_ptr<WebSocket> ws,
                      HTTPServerResponse& response,
-                     std::function<bool(const char* data, const int size)> 
handler)
+                     std::function<bool(const std::vector<char>&)> handler)
 {
     Log::info("Starting Socket Processor.");
 
@@ -322,7 +322,7 @@ void SocketProcessor(std::shared_ptr<WebSocket> ws,
             }
 
             // Call the handler.
-            if (!handler(payload.data(), payload.size()))
+            if (!handler(payload))
             {
                 Log::info("Socket handler flagged for finishing.");
             }
@@ -614,30 +614,20 @@ private:
         queueHandlerThread.start(handler);
         bool normalShutdown = false;
 
-        SocketProcessor(ws, response, [&session, &queue, 
&normalShutdown](const char* data, const int size, const bool singleLine)
+        SocketProcessor(ws, response, [&session, &queue, 
&normalShutdown](const std::vector<char>& payload)
             {
-                // FIXME: There is a race here when a request A gets in the 
queue and
-                // is processed _after_ a later request B, because B gets 
processed
-                // synchronously and A is waiting in the queue thread.
-                // The fix is to push everything into the queue
-                // (i.e. change MessageQueue to vector<char>).
-                const std::string firstLine = getFirstLine(data, size);
+                const auto firstLine = getFirstLine(payload.data(), 
payload.size());
                 time(&session->_lastMessageTime);
-                if (singleLine || firstLine.find("paste") == 0)
+                if (firstLine.compare(0, 10, "disconnect") == 0) // starts 
with "disconnect"
                 {
-                    if (firstLine.compare(0, 10, "disconnect") == 0) // starts 
with "disconnect"
-                    {
-                        normalShutdown = true;
-                        return true;
-                    }
-
-                    queue.put(std::string(data, size));
-                    return true;
+                    normalShutdown = true;
                 }
                 else
                 {
-                    return session->handleInput(data, size);
+                    queue.put(payload);
                 }
+
+                return true;
             });
 
         if (docBroker->getSessionsCount() == 1 && !normalShutdown)
@@ -831,9 +821,9 @@ public:
             lock.unlock();
             MasterProcessSession::AvailableChildSessionCV.notify_one();
 
-            SocketProcessor(ws, response, [&session](const char* data, const 
int size, bool)
+            SocketProcessor(ws, response, [&session](const std::vector<char>& 
payload)
                 {
-                    return session->handleInput(data, size);
+                    return session->handleInput(payload.data(), 
payload.size());
                 });
         }
         catch (const Exception& exc)
diff --git a/loolwsd/MasterProcessSession.cpp b/loolwsd/MasterProcessSession.cpp
index 62e4d6f..0fbf70c 100644
--- a/loolwsd/MasterProcessSession.cpp
+++ b/loolwsd/MasterProcessSession.cpp
@@ -500,7 +500,8 @@ bool MasterProcessSession::getPartPageRectangles(const char 
*buffer, int length)
 
 std::string MasterProcessSession::getSaveAs()
 {
-    return _saveAsQueue.get();
+    const auto payload = _saveAsQueue.get();
+    return std::string(payload.data(), payload.size());
 }
 
 void MasterProcessSession::sendFontRendering(const char *buffer, int length, 
StringTokenizer& tokens)
diff --git a/loolwsd/MessageQueue.hpp b/loolwsd/MessageQueue.hpp
index 2d62173..5a0c439 100644
--- a/loolwsd/MessageQueue.hpp
+++ b/loolwsd/MessageQueue.hpp
@@ -21,7 +21,7 @@ class MessageQueue
 {
 public:
 
-    typedef std::string Payload;
+    typedef std::vector<char> Payload;
 
     MessageQueue()
     {
@@ -34,6 +34,10 @@ public:
 
     /// Thread safe insert the message.
     void put(const Payload& value);
+    void put(const std::string& value)
+    {
+        put(Payload(value.data(), value.data() + value.size()));
+    }
 
     /// Thread safe obtaining of the message.
     Payload get();
diff --git a/loolwsd/QueueHandler.hpp b/loolwsd/QueueHandler.hpp
index 4f3d612..833c331 100644
--- a/loolwsd/QueueHandler.hpp
+++ b/loolwsd/QueueHandler.hpp
@@ -11,6 +11,7 @@
 
 #include "MessageQueue.hpp"
 #include "LOOLSession.hpp"
+#include "LOOLProtocol.hpp"
 #include "Util.hpp"
 
 /// This thread handles incoming messages on a given kit instance.
@@ -36,14 +37,15 @@ public:
         {
             while (true)
             {
-                const std::string input = _queue.get();
-                if (input == "eof")
+                const auto input = _queue.get();
+                const auto firstLine = 
LOOLProtocol::getFirstLine(input.data(), input.size());
+                if (firstLine == "eof")
                 {
                     Log::info("Received EOF. Finishing.");
                     break;
                 }
 
-                if (!_session->handleInput(input.c_str(), input.size()))
+                if (!_session->handleInput(input.data(), input.size()))
                 {
                     Log::info("Socket handler flagged for finishing.");
                     break;
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to