loolwsd/LOOLSession.hpp  |    4 -
 loolwsd/LOOLWSD.cpp      |   41 +++---------------
 loolwsd/Makefile.am      |    5 --
 loolwsd/MessageQueue.cpp |  107 +++++++++++++++++++++++++++++++++++++++++++++++
 loolwsd/MessageQueue.hpp |   82 ++++++++++++++++++++++++++++++++++++
 loolwsd/tsqueue.h        |   75 --------------------------------
 6 files changed, 200 insertions(+), 114 deletions(-)

New commits:
commit 6a1477d8a9ba70e01bfe494f5850ba7eae8ee8c1
Author: Jan Holesovsky <ke...@collabora.com>
Date:   Mon Nov 9 11:36:37 2015 +0100

    loolwsd: Specialize the MessageQueue a bit.
    
    Introduce a bit of hierarchy there, at some stage we'll want to re-order the
    tile requests a bit so that it works better for collaborative editing; for 
the
    moment, removing the duplicate entries is enough.

diff --git a/loolwsd/LOOLSession.hpp b/loolwsd/LOOLSession.hpp
index e84b5d1..2bee3cd 100644
--- a/loolwsd/LOOLSession.hpp
+++ b/loolwsd/LOOLSession.hpp
@@ -29,8 +29,8 @@
 #include <Poco/StringTokenizer.h>
 #include <Poco/Types.h>
 
+#include "MessageQueue.hpp"
 #include "TileCache.hpp"
-#include "tsqueue.h"
 
 // We have three kinds of Websocket sessions
 // 1) Between the master loolwsd server to the end-user LOOL client
@@ -159,7 +159,7 @@ private:
     int _curPart;
     int _loadPart;
     /// Kind::ToClient instances store URLs of completed 'save as' documents.
-    tsqueue<std::string> _saveAsQueue;
+    MessageQueue _saveAsQueue;
 };
 
 class ChildProcessSession final : public LOOLSession
diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index e1cf3d0..3626953 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -105,7 +105,7 @@ DEALINGS IN THE SOFTWARE.
 #include "LOOLProtocol.hpp"
 #include "LOOLSession.hpp"
 #include "LOOLWSD.hpp"
-#include "tsqueue.h"
+#include "MessageQueue.hpp"
 #include "Util.hpp"
 
 using namespace LOOLProtocol;
@@ -149,7 +149,7 @@ using Poco::NamedMutex;
 class QueueHandler: public Runnable
 {
 public:
-    QueueHandler(tsqueue<std::string>& queue):
+    QueueHandler(MessageQueue& queue):
         _queue(queue)
     {
     }
@@ -178,7 +178,7 @@ public:
 
 private:
     std::shared_ptr<LOOLSession> _session;
-    tsqueue<std::string>& _queue;
+    MessageQueue& _queue;
 };
 
 /// Handles the filename part of the convert-to POST request payload.
@@ -347,7 +347,7 @@ public:
             return;
         }
 
-        tsqueue<std::string> queue;
+        BasicTileQueue queue;
         Thread queueHandlerThread;
         QueueHandler handler(queue);
 
@@ -392,22 +392,7 @@ public:
 
                         if (kind == LOOLSession::Kind::ToClient && 
firstLine.size() == static_cast<std::string::size_type>(n))
                         {
-                            // Check if it is a "canceltiles" and in that case 
remove outstanding
-                            // "tile" messages from the queue.
-                            if (tokens.count() == 1 && tokens[0] == 
"canceltiles")
-                            {
-                                queue.remove_if([](std::string& x) {
-                                    return (x.find("tile ") == 0 && 
x.find("id=") == std::string::npos);
-                                });
-
-                                // Also forward the "canceltiles" to the child 
process, if any
-                                session->handleInput(buffer, n);
-                            }
-                            // Filter out duplicated tile messages.
-                            else if ((firstLine.compare(0, 5, "tile ") != 0) 
|| !queue.alreadyInQueue(firstLine))
-                            {
-                                queue.put(firstLine);
-                            }
+                            queue.put(firstLine);
                         }
                         else
                         {
@@ -928,7 +913,7 @@ void LOOLWSD::componentMain()
         std::string hello("child " + std::to_string(_childId) + " " + 
std::to_string(Process::id()));
         session->sendTextFrame(hello);
 
-        tsqueue<std::string> queue;
+        TileQueue queue;
         Thread queueHandlerThread;
         QueueHandler handler(queue);
 
@@ -950,19 +935,7 @@ void LOOLWSD::componentMain()
                 // The only kind of messages a child process receives are the 
single-line ones (?)
                 assert(firstLine.size() == 
static_cast<std::string::size_type>(n));
 
-                // Check if it is a "canceltiles" and in that case remove 
outstanding
-                // "tile" messages from the queue.
-                if (tokens.count() == 1 && tokens[0] == "canceltiles")
-                {
-                    queue.remove_if([](std::string& x) {
-                        return (x.find("tile ") == 0 && x.find("id=") == 
std::string::npos);
-                    });
-                }
-                // Filter out duplicated tile messages.
-                else if ((firstLine.compare(0, 5, "tile ") != 0) || 
!queue.alreadyInQueue(firstLine))
-                {
-                    queue.put(firstLine);
-                }
+                queue.put(firstLine);
             }
         }
         while (n > 0 && (flags & WebSocket::FRAME_OP_BITMASK) != 
WebSocket::FRAME_OP_CLOSE);
diff --git a/loolwsd/Makefile.am b/loolwsd/Makefile.am
index c86f449..be1bcb4 100644
--- a/loolwsd/Makefile.am
+++ b/loolwsd/Makefile.am
@@ -4,7 +4,7 @@ bin_PROGRAMS = loolwsd
 
 dist_bin_SCRIPTS = loolwsd-systemplate-setup
 
-loolwsd_SOURCES = LOOLWSD.cpp LOOLSession.cpp TileCache.cpp Util.cpp 
LOOLProtocol.cpp
+loolwsd_SOURCES = LOOLWSD.cpp LOOLSession.cpp MessageQueue.cpp TileCache.cpp 
Util.cpp LOOLProtocol.cpp
 
 noinst_PROGRAMS = loadtest connect lokitclient
 
@@ -14,8 +14,7 @@ connect_SOURCES = Connect.cpp Util.cpp LOOLProtocol.cpp
 
 lokitclient_SOURCES = LOKitClient.cpp Util.cpp
 
-noinst_HEADERS = LOKitHelper.hpp LOOLProtocol.hpp LOOLSession.hpp LOOLWSD.hpp 
LoadTest.hpp TileCache.hpp Util.hpp \
-                 tsqueue.h \
+noinst_HEADERS = LOKitHelper.hpp LOOLProtocol.hpp LOOLSession.hpp LOOLWSD.hpp 
LoadTest.hpp MessageQueue.hpp TileCache.hpp Util.hpp \
                  bundled/include/LibreOfficeKit/LibreOfficeKit.h 
bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h \
                  bundled/include/LibreOfficeKit/LibreOfficeKitInit.h 
bundled/include/LibreOfficeKit/LibreOfficeKitTypes.h
 
diff --git a/loolwsd/MessageQueue.cpp b/loolwsd/MessageQueue.cpp
new file mode 100644
index 0000000..f37c5b8
--- /dev/null
+++ b/loolwsd/MessageQueue.cpp
@@ -0,0 +1,107 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "MessageQueue.hpp"
+
+#include <algorithm>
+
+MessageQueue::~MessageQueue()
+{
+    clear();
+}
+
+void MessageQueue::put(const std::string& value)
+{
+    std::unique_lock<std::mutex> lock(_mutex);
+    put_impl(value);
+    lock.unlock();
+    _cv.notify_one();
+}
+
+std::string MessageQueue::get()
+{
+    std::unique_lock<std::mutex> lock(_mutex);
+    _cv.wait(lock, [this] { return wait_impl(); });
+    return get_impl();
+}
+
+void MessageQueue::clear()
+{
+    std::unique_lock<std::mutex> lock(_mutex);
+    _queue.clear();
+}
+
+void MessageQueue::put_impl(const std::string& value)
+{
+    _queue.push_back(value);
+}
+
+bool MessageQueue::wait_impl() const
+{
+    return _queue.size() > 0;
+}
+
+std::string MessageQueue::get_impl()
+{
+    std::string result = _queue.front();
+    _queue.pop_front();
+    return result;
+}
+
+void MessageQueue::clear_impl()
+{
+    _queue.clear();
+}
+
+void BasicTileQueue::put_impl(const std::string& value)
+{
+    if (value == "canceltiles")
+    {
+        // remove all the existing tiles from the queue
+        _queue.erase(std::remove_if(_queue.begin(), _queue.end(),
+                    [](const std::string& v) {
+                        // must not remove the tiles with 'id=', they are 
special, used
+                        // eg. for previews etc.
+                        return (v.compare(0, 5, "tile ") == 0) && 
(v.find("id=") == std::string::npos);
+                    }
+                    ),
+                _queue.end());
+
+        // put the "canceltiles" in front of other messages
+        _queue.push_front(value);
+    }
+    else
+        MessageQueue::put_impl(value);
+}
+
+void TileQueue::put_impl(const std::string& value)
+{
+    if (value.compare(0, 5, "tile ") == 0)
+    {
+        // TODO: implement a real re-ordering here, so that the tiles closest 
to
+        // the cursor are returned first.
+        // * we will want to put just a general "tile" message to the queue
+        // * add a std::set that handles the tiles
+        // * change the get_impl() to decide which tile is the correct one to
+        //   be returned
+        // * we will also need to be informed about the position of the cursor
+        //   so that get_impl() returns optimal results
+        //
+        // For now: just don't put duplicates into the queue
+        for (auto it = _queue.cbegin(); it != _queue.cend(); ++it)
+        {
+            if (value == *it)
+                return;
+        }
+    }
+
+    BasicTileQueue::put_impl(value);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/loolwsd/MessageQueue.hpp b/loolwsd/MessageQueue.hpp
new file mode 100644
index 0000000..f1b8996
--- /dev/null
+++ b/loolwsd/MessageQueue.hpp
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_MESSAGEQUEUE_HPP
+#define INCLUDED_MESSAGEQUEUE_HPP
+
+#include "config.h"
+
+#include <condition_variable>
+#include <mutex>
+#include <deque>
+
+/** Thread-safe message queue (FIFO).
+*/
+class MessageQueue
+{
+public:
+    MessageQueue() {}
+    virtual ~MessageQueue();
+
+    MessageQueue(const MessageQueue&) = delete;
+    MessageQueue& operator=(const MessageQueue&) = delete;
+
+    /// Thread safe insert the message.
+    void put(const std::string& value);
+
+    /// Thread safe obtaining of the message.
+    std::string get();
+
+    /// Thread safe removal of all the pending messages.
+    void clear();
+
+private:
+    std::mutex _mutex;
+    std::condition_variable _cv;
+
+protected:
+    virtual void put_impl(const std::string& value);
+
+    virtual bool wait_impl() const;
+
+    virtual std::string get_impl();
+
+    virtual void clear_impl();
+
+    std::deque<std::string> _queue;
+};
+
+/** MessageQueue specialized for handling of tiles.
+
+Used for basic handling of incoming requests, only can remove tiles when it
+gets a "canceltiles" command.
+*/
+class BasicTileQueue : public MessageQueue
+{
+protected:
+    virtual void put_impl(const std::string& value);
+};
+
+/** MessageQueue specialized for priority handling of tiles.
+
+This class builds on BasicTileQueuee, and additonaly provides de-duplication
+of tile requests.
+
+TODO: we'll need to add reordering of the tiles at some stage here too - so
+that the ones closest to the cursor position are returned first.
+*/
+class TileQueue : public BasicTileQueue
+{
+protected:
+    virtual void put_impl(const std::string& value);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/loolwsd/tsqueue.h b/loolwsd/tsqueue.h
deleted file mode 100644
index 94a36cd..0000000
--- a/loolwsd/tsqueue.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-#ifndef INCLUDED_TSQUEUE_H
-#define INCLUDED_TSQUEUE_H
-
-#include "config.h"
-
-#include <condition_variable>
-#include <mutex>
-#include <deque>
-
-// Thread-safe queue
-
-template <class T>
-class tsqueue
-{
-public:
-    void put(const T& value)
-    {
-        std::unique_lock<std::mutex> lock(_mutex);
-        _queue.push_back(value);
-        lock.unlock();
-        _cv.notify_one();
-    }
-
-    T get()
-    {
-        std::unique_lock<std::mutex> lock(_mutex);
-        _cv.wait(lock, [this] { return _queue.size() > 0; });
-        T result = _queue.front();
-        _queue.pop_front();
-        return result;
-    }
-
-    void clear()
-    {
-        std::unique_lock<std::mutex> lock(_mutex);
-        while (_queue.size())
-            _queue.pop_front();
-    }
-
-    template<class UnaryPredicate>
-    void remove_if(UnaryPredicate p)
-    {
-        std::unique_lock<std::mutex> lock(_mutex);
-        _queue.erase(std::remove_if(_queue.begin(), _queue.end(), p),
-                     _queue.end());
-    }
-
-    bool alreadyInQueue(std::string cmd) {
-        std::unique_lock<std::mutex> lock(_mutex);
-        for (auto it = _queue.cbegin(); it != _queue.cend(); ++it) {
-            if (cmd == *it) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-private:
-    std::mutex _mutex;
-    std::condition_variable _cv;
-    std::deque<T> _queue;
-};
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to