[Libreoffice-commits] online.git: loolwsd/Admin.hpp loolwsd/AdminModel.hpp loolwsd/LOOLBroker.cpp loolwsd/LOOLWSD.cpp loolwsd/Makefile.am

Pranav Kant pranavk at collabora.com
Thu Mar 3 03:35:06 UTC 2016


 loolwsd/Admin.hpp      |   94 +++++++++++++++++++++++++++++++++++++++++++++++--
 loolwsd/AdminModel.hpp |   32 ++++++++++++++++
 loolwsd/LOOLBroker.cpp |   11 +++++
 loolwsd/LOOLWSD.cpp    |   37 +++++++++++++++++--
 loolwsd/Makefile.am    |    2 -
 5 files changed, 168 insertions(+), 8 deletions(-)

New commits:
commit c5aa122fcb752fa835f9a9557f54c52c98b597f0
Author: Pranav Kant <pranavk at collabora.com>
Date:   Wed Feb 24 22:28:05 2016 +0530

    loolwsd: Create notification pipe
    
    ... and Admin and AdminModel containing all the required data
    that we need to expose to Admin panel.
    
    Admin processor will keep listening to any data on this
    notification pipe and update AdminModel accordingly.
    
    Change-Id: I0dd6f07ae60158733c34d17f53a35def70600513
    Reviewed-on: https://gerrit.libreoffice.org/22780
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>

diff --git a/loolwsd/Admin.hpp b/loolwsd/Admin.hpp
index b963702..759647b 100644
--- a/loolwsd/Admin.hpp
+++ b/loolwsd/Admin.hpp
@@ -17,6 +17,7 @@
 #include <mutex>
 #include <ostream>
 #include <set>
+#include <sys/poll.h>
 
 #include <Poco/Net/WebSocket.h>
 #include <Poco/Buffer.h>
@@ -29,6 +30,7 @@
 #include <Poco/Net/HTTPServerRequest.h>
 #include <Poco/Net/HTTPServerResponse.h>
 
+#include "AdminModel.hpp"
 #include "Common.hpp"
 #include "LOOLProtocol.hpp"
 #include "Util.hpp"
@@ -53,6 +55,8 @@ using Poco::Runnable;
 using Poco::StringTokenizer;
 using Poco::Net::Socket;
 
+const std::string FIFO_NOTIFY = "loolnotify.fifo";
+
 /// Handle admin requests.
 class AdminRequestHandler: public HTTPRequestHandler
 {
@@ -204,10 +208,12 @@ public:
 class Admin : public Runnable
 {
 public:
-    Admin(const int brokerPipe) :
-        _srv(new AdminRequestHandlerFactory(), ServerSocket(ADMIN_PORT_NUMBER), new HTTPServerParams)
+    Admin(const int brokerPipe, const int notifyPipe) :
+        _srv(new AdminRequestHandlerFactory(), ServerSocket(ADMIN_PORT_NUMBER), new HTTPServerParams),
+        _model(AdminModel())
     {
         Admin::BrokerPipe = brokerPipe;
+        Admin::NotifyPipe = notifyPipe;
     }
 
     ~Admin()
@@ -218,22 +224,104 @@ public:
 
     static int getBrokerPid() { return Admin::BrokerPipe; }
 
+    void handleInput(std::string& message)
+    {
+        std::cout << message << std::endl;
+    }
+
     void run() override
     {
         Log::info("Listening on Admin port " + std::to_string(ADMIN_PORT_NUMBER));
 
         // Start a server listening on the admin port.
         _srv.start();
+
+        // Start listening for data changes
+        std::string message;
+        char buffer[READ_BUFFER_SIZE];
+        char* start;
+        char* end;
+
+        struct pollfd pollPipeNotify;
+        ssize_t bytes = -1;
+
+        pollPipeNotify.fd = NotifyPipe;
+        pollPipeNotify.events = POLLIN;
+        pollPipeNotify.revents = 0;
+
+        start = buffer;
+        end = buffer;
+
+        static const std::string thread_name = "admin_thread";
+
+        if (prctl(PR_SET_NAME, reinterpret_cast<unsigned long>(thread_name.c_str()), 0, 0, 0) != 0)
+            Log::error("Cannot set thread name to " + thread_name + ".");
+
+        Log::info("Thread [" + thread_name + "] started.");
+
+        while (!TerminationFlag)
+        {
+            if (start == end)
+            {
+                if (poll(&pollPipeNotify, 1, POLL_TIMEOUT_MS) < 0)
+                {
+                    Log::error("Failed to poll pipe [" + FIFO_NOTIFY + "].");
+                    continue;
+                }
+                else if (pollPipeNotify.revents & (POLLIN | POLLPRI))
+                {
+                    bytes = Util::readFIFO(NotifyPipe, buffer, sizeof(buffer));
+                    if (bytes < 0)
+                    {
+                        start = end = nullptr;
+                        Log::error("Error reading message from pipe [" + FIFO_NOTIFY + "].");
+                        continue;
+                    }
+                    start = buffer;
+                    end = buffer + bytes;
+                }
+                else if (pollPipeNotify.revents & (POLLERR | POLLHUP))
+                {
+                    Log::error("Broken pipe [" + FIFO_NOTIFY + "] with wsd.");
+                    break;
+                }
+            }
+
+            if (start != end)
+            {
+                char byteChar = *start++;
+                while (start != end && byteChar != '\r' && byteChar != '\n')
+                {
+                    message += byteChar;
+                    byteChar = *start++;
+                }
+
+                if (byteChar == '\r' && *start == '\n')
+                {
+                    start++;
+                    Log::trace("NotifyData: " + message);
+                    if (message == "eof")
+                        break;
+
+                    handleInput(message);
+                    message.clear();
+                }
+            }
+        }
+        Log::debug("Thread [" + thread_name + "] finished.");
     }
 
 private:
     HTTPServer _srv;
+    AdminModel _model;
+
     static int BrokerPipe;
+    static int NotifyPipe;
 };
 
 //TODO: Clean up with something more elegant.
 int Admin::BrokerPipe;
-
+int Admin::NotifyPipe;
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/loolwsd/AdminModel.hpp b/loolwsd/AdminModel.hpp
new file mode 100644
index 0000000..438666f
--- /dev/null
+++ b/loolwsd/AdminModel.hpp
@@ -0,0 +1,32 @@
+/* -*- 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_ADMIN_MODEL_HPP
+#define INCLUDED_ADMIN_MODEL_HPP
+
+#include "config.h"
+
+#include "Util.hpp"
+
+class AdminModel
+{
+public:
+    AdminModel()
+    {
+        Log::info("AdminModel ctor.");
+    }
+
+    ~AdminModel()
+    {
+        Log::info("AdminModel dtor.");
+    }
+};
+
+#endif
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/loolwsd/LOOLBroker.cpp b/loolwsd/LOOLBroker.cpp
index a4b8940..a9ace30 100644
--- a/loolwsd/LOOLBroker.cpp
+++ b/loolwsd/LOOLBroker.cpp
@@ -31,11 +31,13 @@ typedef int (LokHookPreInit)  ( const char *install_path, const char *user_profi
 using Poco::ProcessHandle;
 
 const std::string FIFO_LOOLWSD = "loolwsdfifo";
+const std::string FIFO_NOTIFY = "loolnotify.fifo";
 const std::string BROKER_SUFIX = ".fifo";
 const std::string BROKER_PREFIX = "lokit";
 
 static int readerChild = -1;
 static int readerBroker = -1;
+static int writerNotify = -1;
 
 static std::string loolkitPath;
 static std::atomic<unsigned> forkCounter;
@@ -777,6 +779,14 @@ int main(int argc, char** argv)
         std::exit(Application::EXIT_SOFTWARE);
     }
 
+    // Open notify pipe
+    const std::string pipeNotify = Path(pipePath, FIFO_NOTIFY).toString();
+    if ((writerNotify = open(pipeNotify.c_str(), O_WRONLY) ) < 0)
+    {
+        Log::error("Error: pipe opened for writing.");
+        exit(Application::EXIT_SOFTWARE);
+    }
+
     // Initialize LoKit and hope we can fork and save memory by sharing pages.
     const bool sharePages = std::getenv("LOK_NO_PREINIT") == nullptr
                           ? globalPreinit(loTemplate)
@@ -945,6 +955,7 @@ int main(int argc, char** argv)
     _childProcesses.clear();
 
     pipeThread.join();
+    close(writerNotify);
     close(readerChild);
     close(readerBroker);
 
diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index 4d8558b..8ad52d7 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -970,6 +970,35 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/)
         return Application::EXIT_SOFTWARE;
     }
 
+    // Open notify pipe
+    int pipeFlags = O_RDONLY | O_NONBLOCK;
+    int notifyPipe = -1;
+    const std::string pipeNotify = Path(pipePath, FIFO_NOTIFY).toString();
+    if (mkfifo(pipeNotify.c_str(), 0666) < 0 && errno != EEXIST)
+    {
+        Log::error("Error: Failed to create pipe FIFO [" + FIFO_NOTIFY + "].");
+        exit(Application::EXIT_SOFTWARE);
+    }
+
+    if ((notifyPipe = open(pipeNotify.c_str(), pipeFlags) ) < 0)
+    {
+        Log::error("Error: pipe opened for reading.");
+        exit(Application::EXIT_SOFTWARE);
+    }
+
+    if ((pipeFlags = fcntl(notifyPipe, F_GETFL, 0)) < 0)
+    {
+        Log::error("Error: failed to get pipe flags [" + FIFO_NOTIFY + "].");
+        exit(Application::EXIT_SOFTWARE);
+    }
+
+    pipeFlags &= ~O_NONBLOCK;
+    if (fcntl(notifyPipe, F_SETFL, pipeFlags) < 0)
+    {
+        Log::error("Error: failed to set pipe flags [" + FIFO_NOTIFY + "].");
+        exit(Application::EXIT_SOFTWARE);
+    }
+
     const Process::PID brokerPid = createBroker();
     if (brokerPid < 0)
     {
@@ -1004,16 +1033,16 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/)
 
     srv2.start();
 
-    // Start the Admin manager.
-    Admin admin(BrokerWritePipe);
-    threadPool.start(admin);
-
     if ( (BrokerWritePipe = open(pipeLoolwsd.c_str(), O_WRONLY) ) < 0 )
     {
         Log::error("Error: failed to open pipe [" + pipeLoolwsd + "] write only.");
         return Application::EXIT_SOFTWARE;
     }
 
+    // Start the Admin manager.
+    Admin admin(BrokerWritePipe, notifyPipe);
+    threadPool.start(admin);
+
     TestInput input(*this, svs, srv);
     Thread inputThread;
     if (LOOLWSD::DoTest)
diff --git a/loolwsd/Makefile.am b/loolwsd/Makefile.am
index 37ca105..cbd6f02 100644
--- a/loolwsd/Makefile.am
+++ b/loolwsd/Makefile.am
@@ -29,7 +29,7 @@ loolmap_SOURCES = loolmap.c
 
 noinst_HEADERS = LOKitHelper.hpp LOOLProtocol.hpp LOOLSession.hpp MasterProcessSession.hpp ChildProcessSession.hpp \
                  LOOLWSD.hpp LoadTest.hpp MessageQueue.hpp TileCache.hpp Util.hpp Png.hpp Common.hpp Capabilities.hpp \
-                 Rectangle.hpp QueueHandler.hpp Admin.hpp Auth.hpp Storage.hpp \
+                 Rectangle.hpp QueueHandler.hpp Admin.hpp Auth.hpp Storage.hpp AdminModel.hpp \
                  bundled/include/LibreOfficeKit/LibreOfficeKit.h bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h \
                  bundled/include/LibreOfficeKit/LibreOfficeKitInit.h bundled/include/LibreOfficeKit/LibreOfficeKitTypes.h
 


More information about the Libreoffice-commits mailing list