[Libreoffice-commits] online.git: loolwsd/Admin.cpp loolwsd/Common.hpp loolwsd/LOOLBroker.cpp loolwsd/LOOLKit.cpp loolwsd/LOOLWSD.cpp loolwsd/LOOLWSD.hpp loolwsd/MasterProcessSession.cpp

Henry Castro hcastro at collabora.com
Sun Apr 3 12:12:22 UTC 2016


 loolwsd/Admin.cpp                |    2 -
 loolwsd/Common.hpp               |    2 -
 loolwsd/LOOLBroker.cpp           |   58 +++++++++++++++++++++---------
 loolwsd/LOOLKit.cpp              |    7 +++
 loolwsd/LOOLWSD.cpp              |   75 ++++++++++++++++++++++-----------------
 loolwsd/LOOLWSD.hpp              |    2 +
 loolwsd/MasterProcessSession.cpp |    6 +--
 7 files changed, 99 insertions(+), 53 deletions(-)

New commits:
commit 97c8f35ddffe9b363bb2544a40d81f623934a0ed
Author: Henry Castro <hcastro at collabora.com>
Date:   Sun Apr 3 08:12:10 2016 -0400

    loolwsd: replace fifo for socket WSD -> Broker

diff --git a/loolwsd/Admin.cpp b/loolwsd/Admin.cpp
index 2ad3d3d..800c2bc 100644
--- a/loolwsd/Admin.cpp
+++ b/loolwsd/Admin.cpp
@@ -194,7 +194,7 @@ void AdminRequestHandler::handleWSRequests(HTTPServerRequest& request, HTTPServe
                         {
                             if (std::stoi(tokens[1]))
                             {
-                                IoUtil::writeFIFO(LOOLWSD::BrokerWritePipe, firstLine + " \r\n");
+                                LOOLWSD::DlgBroker->sendMessage(firstLine);
                             }
                         }
                         catch(std::exception& e)
diff --git a/loolwsd/Common.hpp b/loolwsd/Common.hpp
index 40613e3..27279c5 100644
--- a/loolwsd/Common.hpp
+++ b/loolwsd/Common.hpp
@@ -18,6 +18,7 @@ constexpr int MAX_SESSIONS = 1024;
 
 constexpr int DEFAULT_CLIENT_PORT_NUMBER = 9980;
 constexpr int MASTER_PORT_NUMBER = 9981;
+constexpr int COMMAND_PORT_NUMBER = 9982;
 constexpr int INTERVAL_PROBES = 10;
 constexpr int MAINTENANCE_INTERVAL = 1;
 constexpr int CHILD_TIMEOUT_SECS = 10;
@@ -34,7 +35,6 @@ constexpr int READ_BUFFER_SIZE = 2048;
 constexpr int SMALL_MESSAGE_SIZE = READ_BUFFER_SIZE / 2;
 
 constexpr auto CHILD_URI = "/loolws/child?";
-constexpr auto FIFO_LOOLWSD = "loolwsdfifo";
 constexpr auto FIFO_PATH = "pipe";
 constexpr auto JAILED_DOCUMENT_ROOT = "/user/docs/";
 constexpr auto SSL_KEY_FILE = "key.pem";
diff --git a/loolwsd/LOOLBroker.cpp b/loolwsd/LOOLBroker.cpp
index d79b032..ac46e84 100644
--- a/loolwsd/LOOLBroker.cpp
+++ b/loolwsd/LOOLBroker.cpp
@@ -35,7 +35,6 @@ const std::string BROKER_SUFIX = ".fifo";
 const std::string BROKER_PREFIX = "lokit";
 
 static int readerChild = -1;
-static int readerBroker = -1;
 
 static std::string loolkitPath;
 static std::atomic<unsigned> forkCounter;
@@ -174,11 +173,12 @@ namespace
     }
 }
 
-class PipeRunnable: public Runnable
+class CommandRunnable: public Runnable
 {
 public:
-    PipeRunnable() :
-        _childPipeReader("child_pipe_rd", readerChild)
+    CommandRunnable(const std::shared_ptr<DialogSocket>& dlgWsd) :
+        _childPipeReader("child_pipe_rd", readerChild),
+        _dlgWsd(dlgWsd)
     {
     }
 
@@ -271,21 +271,39 @@ public:
     void run() override
     {
         static const std::string thread_name = "brk_pipe_reader";
+        const Poco::Timespan waitTime(POLL_TIMEOUT_MS * 1000);
 
         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::debug("Thread [" + thread_name + "] started.");
 
-        IoUtil::PipeReader pipeReader(FIFO_LOOLWSD, readerBroker);
-        pipeReader.process([this](std::string& message) { handleInput(message); return true; },
-                           []() { return TerminationFlag; });
+        try
+        {
+            while (!TerminationFlag)
+            {
+                if (_dlgWsd->poll(waitTime, Socket::SELECT_READ))
+                {
+                    std::string message;
+                    _dlgWsd->receiveMessage(message);
+                    handleInput(message);
+                }
+            }
+            _dlgWsd->shutdown();
+        }
+        catch (const Exception& exc)
+        {
+            Log::error() << "CommandRunnable::run: Exception: " << exc.displayText()
+                         << (exc.nested() ? " (" + exc.nested()->displayText() + ")" : "")
+                         << Log::end;
+        }
 
         Log::debug("Thread [" + thread_name + "] finished.");
     }
 
 private:
     IoUtil::PipeReader _childPipeReader;
+    std::shared_ptr<DialogSocket> _dlgWsd;
 };
 
 /// Initializes LibreOfficeKit for cross-fork re-use.
@@ -553,11 +571,18 @@ int main(int argc, char** argv)
     assert(!childRoot.empty());
     assert(numPreSpawnedChildren >= 1);
 
-    const Path pipePath = Path::forDirectory(childRoot + Path::separator() + FIFO_PATH);
-    const std::string pipeLoolwsd = Path(pipePath, FIFO_LOOLWSD).toString();
-    if ( (readerBroker = open(pipeLoolwsd.c_str(), O_RDONLY) ) < 0 )
+    std::shared_ptr<DialogSocket> dlgWsd = std::make_shared<DialogSocket>();
+    const Poco::Timespan waitTime(POLL_TIMEOUT_MS * 1000);
+
+    try
     {
-        Log::error("Error: failed to open pipe [" + pipeLoolwsd + "] read only. Exiting.");
+        dlgWsd->connect(SocketAddress("localhost", COMMAND_PORT_NUMBER), waitTime);
+    }
+    catch (const Exception& exc)
+    {
+        Log::error() << "LOOLBroker::main: Exception: " << exc.displayText()
+                     << (exc.nested() ? " (" + exc.nested()->displayText() + ")" : "")
+                     << Log::end;
         std::exit(Application::EXIT_SOFTWARE);
     }
 
@@ -568,6 +593,8 @@ int main(int argc, char** argv)
         Log::info("Note: LOK_VIEW_CALLBACK is not set.");
 
     int pipeFlags = O_RDONLY | O_NONBLOCK;
+
+    const Path pipePath = Path::forDirectory(childRoot + Path::separator() + FIFO_PATH);
     const std::string pipeBroker = Path(pipePath, FIFO_BROKER).toString();
     if (mkfifo(pipeBroker.c_str(), 0666) < 0 && errno != EEXIST)
     {
@@ -630,10 +657,10 @@ int main(int argc, char** argv)
         dropCapability(CAP_FOWNER);
     }
 
-    PipeRunnable pipeHandler;
-    Poco::Thread pipeThread;
+    CommandRunnable commandHandler(dlgWsd);
+    Poco::Thread commandThread;
 
-    pipeThread.start(pipeHandler);
+    commandThread.start(commandHandler);
 
     Log::info("loolbroker is ready.");
 
@@ -807,10 +834,9 @@ int main(int argc, char** argv)
     _childProcesses.clear();
     _newChildProcesses.clear();
 
-    pipeThread.join();
+    commandThread.join();
     close(writerNotify);
     close(readerChild);
-    close(readerBroker);
 
     Log::info("Process [loolbroker] finished.");
     return Application::EXIT_OK;
diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp
index f8699b3..cb46505 100644
--- a/loolwsd/LOOLKit.cpp
+++ b/loolwsd/LOOLKit.cpp
@@ -34,6 +34,9 @@
 #include <Poco/Net/HTTPResponse.h>
 #include <Poco/Net/NetException.h>
 #include <Poco/Net/WebSocket.h>
+#include <Poco/Net/ServerSocket.h>
+#include <Poco/Net/DialogSocket.h>
+#include <Poco/Net/SocketAddress.h>
 #include <Poco/Process.h>
 #include <Poco/Runnable.h>
 #include <Poco/StringTokenizer.h>
@@ -62,7 +65,11 @@ using Poco::File;
 using Poco::Net::HTTPClientSession;
 using Poco::Net::HTTPRequest;
 using Poco::Net::HTTPResponse;
+using Poco::Net::Socket;
 using Poco::Net::WebSocket;
+using Poco::Net::ServerSocket;
+using Poco::Net::DialogSocket;
+using Poco::Net::SocketAddress;
 using Poco::Path;
 using Poco::Process;
 using Poco::Runnable;
diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index 1dd6eef..5fe1bd4 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -94,6 +94,7 @@ DEALINGS IN THE SOFTWARE.
 #include <Poco/Net/SecureServerSocket.h>
 #include <Poco/Net/ServerSocket.h>
 #include <Poco/Net/SocketAddress.h>
+#include <Poco/Net/DialogSocket.h>
 #include <Poco/Net/WebSocket.h>
 #include <Poco/Path.h>
 #include <Poco/Process.h>
@@ -147,6 +148,7 @@ using Poco::Net::SecureServerSocket;
 using Poco::Net::ServerSocket;
 using Poco::Net::Socket;
 using Poco::Net::SocketAddress;
+using Poco::Net::DialogSocket;
 using Poco::Net::WebSocket;
 using Poco::Net::WebSocketException;
 using Poco::Path;
@@ -464,9 +466,9 @@ private:
             session->setEditLock(true);
 
         // Request a kit process for this doc.
-        const std::string aMessage = "request " + id + " " + docKey + "\n";
-        Log::debug("MasterToBroker: " + aMessage.substr(0, aMessage.length() - 1));
-        IoUtil::writeFIFO(LOOLWSD::BrokerWritePipe, aMessage);
+        const std::string message = "request " + id + " " + docKey;
+        Log::debug("MasterToBroker: " + message);
+        LOOLWSD::DlgBroker->sendMessage(message);
 
         QueueHandler handler(queue, session, "wsd_queue_" + session->getId());
 
@@ -879,7 +881,7 @@ private:
 };
 
 std::atomic<unsigned> LOOLWSD::NextSessionId;
-int LOOLWSD::BrokerWritePipe = -1;
+std::unique_ptr<DialogSocket> LOOLWSD::DlgBroker;
 std::string LOOLWSD::Cache = LOOLWSD_CACHEDIR;
 std::string LOOLWSD::SysTemplate;
 std::string LOOLWSD::LoTemplate;
@@ -1080,23 +1082,47 @@ void LOOLWSD::displayVersion()
 
 Process::PID LOOLWSD::createBroker()
 {
-    Process::Args args;
+    Process::PID brokerPid = -1;
 
-    args.push_back("--losubpath=" + LOOLWSD::LoSubPath);
-    args.push_back("--systemplate=" + SysTemplate);
-    args.push_back("--lotemplate=" + LoTemplate);
-    args.push_back("--childroot=" + ChildRoot);
-    args.push_back("--numprespawns=" + std::to_string(NumPreSpawnedChildren));
-    args.push_back("--clientport=" + std::to_string(ClientPortNumber));
+    try
+    {
+        Process::Args args;
+
+        args.push_back("--losubpath=" + LOOLWSD::LoSubPath);
+        args.push_back("--systemplate=" + SysTemplate);
+        args.push_back("--lotemplate=" + LoTemplate);
+        args.push_back("--childroot=" + ChildRoot);
+        args.push_back("--numprespawns=" + std::to_string(NumPreSpawnedChildren));
+        args.push_back("--clientport=" + std::to_string(ClientPortNumber));
+
+        const std::string brokerPath = Path(Application::instance().commandPath()).parent().toString() + "loolbroker";
+        const Poco::Timespan waitTime(POLL_TIMEOUT_MS * 1000);
 
-    const std::string brokerPath = Path(Application::instance().commandPath()).parent().toString() + "loolbroker";
+        Log::info("Launching Broker #1: " + brokerPath + " " +
+                  Poco::cat(std::string(" "), args.begin(), args.end()));
 
-    Log::info("Launching Broker #1: " + brokerPath + " " +
-              Poco::cat(std::string(" "), args.begin(), args.end()));
+        ServerSocket srvCommand(COMMAND_PORT_NUMBER);
+        ProcessHandle child = Process::launch(brokerPath, args);
 
-    ProcessHandle child = Process::launch(brokerPath, args);
+        if (srvCommand.poll(waitTime, Socket::SELECT_READ))
+        {
+            DlgBroker.reset(new DialogSocket(srvCommand.acceptConnection()));
+            brokerPid = child.id();
+        }
+        else
+        {
+            Log::error("Error: failed to socket connection with broker.");
+            Util::requestTermination(child.id());
+        }
+    }
+    catch (const Exception& exc)
+    {
+        Log::error() << "LOOLWSD::createBroker: Exception: " << exc.displayText()
+                     << (exc.nested() ? " (" + exc.nested()->displayText() + ")" : "")
+                     << Log::end;
+    }
 
-    return child.id();
+    return brokerPid;
 }
 
 int LOOLWSD::main(const std::vector<std::string>& /*args*/)
@@ -1162,13 +1188,6 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/)
         return Application::EXIT_SOFTWARE;
     }
 
-    const std::string pipeLoolwsd = Path(pipePath, FIFO_LOOLWSD).toString();
-    if (mkfifo(pipeLoolwsd.c_str(), 0666) < 0 && errno != EEXIST)
-    {
-        Log::error("Error: Failed to create pipe FIFO [" + pipeLoolwsd + "].");
-        return Application::EXIT_SOFTWARE;
-    }
-
     // Open notify pipe
     int pipeFlags = O_RDONLY | O_NONBLOCK;
     int notifyPipe = -1;
@@ -1237,12 +1256,6 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/)
 
     srv2.start();
 
-    if ( (BrokerWritePipe = open(pipeLoolwsd.c_str(), O_WRONLY) ) < 0 )
-    {
-        Log::error("Error: failed to open pipe [" + pipeLoolwsd + "] write only.");
-        return Application::EXIT_SOFTWARE;
-    }
-
     threadPool.start(admin);
 
     TestInput input(*this, svs, srv);
@@ -1380,15 +1393,13 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/)
     threadPool.joinAll();
 
     // Terminate child processes
-    IoUtil::writeFIFO(LOOLWSD::BrokerWritePipe, "eof\n");
+    DlgBroker->shutdown();
     Log::info("Requesting child process " + std::to_string(brokerPid) + " to terminate");
     Util::requestTermination(brokerPid);
 
     // wait broker process finish
     waitpid(brokerPid, &status, WUNTRACED);
 
-    close(BrokerWritePipe);
-
     Log::info("Cleaning up childroot directory [" + ChildRoot + "].");
     std::vector<std::string> jails;
     File(ChildRoot).list(jails);
diff --git a/loolwsd/LOOLWSD.hpp b/loolwsd/LOOLWSD.hpp
index 59d7111..9d5e5d3 100644
--- a/loolwsd/LOOLWSD.hpp
+++ b/loolwsd/LOOLWSD.hpp
@@ -19,6 +19,7 @@
 #include <Poco/Random.h>
 #include <Poco/Util/OptionSet.h>
 #include <Poco/Util/ServerApplication.h>
+#include <Poco/Net/DialogSocket.h>
 
 #include "Auth.hpp"
 #include "Common.hpp"
@@ -36,6 +37,7 @@ public:
     // An Application is a singleton anyway,
     // so just keep these as statics.
     static std::atomic<unsigned> NextSessionId;
+    static std::unique_ptr<Poco::Net::DialogSocket> DlgBroker;
     static int NumPreSpawnedChildren;
     static int BrokerWritePipe;
     static bool DoTest;
diff --git a/loolwsd/MasterProcessSession.cpp b/loolwsd/MasterProcessSession.cpp
index 432e751..f8a21b6 100644
--- a/loolwsd/MasterProcessSession.cpp
+++ b/loolwsd/MasterProcessSession.cpp
@@ -782,9 +782,9 @@ void MasterProcessSession::dispatchChild()
         {
             Log::info() << "Retrying child permission... " << retries << Log::end;
             // request again new URL session
-            const std::string message = "request " + getId() + " " + _docBroker->getDocKey() + '\n';
-            Log::trace("MasterToBroker: " + message.substr(0, message.length()-1));
-            IoUtil::writeFIFO(LOOLWSD::BrokerWritePipe, message);
+            const std::string message = "request " + getId() + " " + _docBroker->getDocKey();
+            Log::trace("MasterToBroker: " + message);
+            LOOLWSD::DlgBroker->sendMessage(message);
         }
     }
 


More information about the Libreoffice-commits mailing list