Makefile.am              |    1 
 net/ServerSocket.hpp     |    4 
 net/Socket.cpp           |   39 +++++-
 net/Socket.hpp           |    1 
 net/WebSocketHandler.hpp |    3 
 wsd/DocumentBroker.cpp   |    3 
 wsd/DocumentBroker.hpp   |   38 ++---
 wsd/LOOLWSD.cpp          |  301 ++++++++++++++++++++++++++++++++++++++---------
 8 files changed, 308 insertions(+), 82 deletions(-)

New commits:
commit 8271df609e7282afdaea271fe1ef9cfd4d741bcf
Author: Michael Meeks <michael.me...@collabora.com>
Date:   Mon Mar 6 21:26:53 2017 +0000

    Dump buffer contents as hex if we have them.

diff --git a/net/Socket.cpp b/net/Socket.cpp
index 88502c8..49e6717 100644
--- a/net/Socket.cpp
+++ b/net/Socket.cpp
@@ -7,6 +7,9 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
+#include <stdio.h>
+#include <ctype.h>
+
 #include "Socket.hpp"
 #include "ServerSocket.hpp"
 
@@ -60,12 +63,46 @@ void ServerSocket::dumpState()
     std::cerr << "\t" << getFD() << "\t<accept>\n";
 }
 
+namespace {
+
+void dump_hex (const char *legend, const char *prefix, std::vector<char> 
buffer)
+{
+    unsigned int i, j;
+    fprintf (stderr, "%s", legend);
+    for (j = 0; j < buffer.size() + 15; j += 16)
+    {
+        fprintf (stderr, "%s0x%.4x  ", prefix, j);
+        for (i = 0; i < 16; i++)
+        {
+            if ((j + i) < buffer.size())
+                fprintf (stderr, "%.2x ", (unsigned char)buffer[j+i]);
+            else
+                fprintf (stderr, "   ");
+            if (i == 8)
+                fprintf (stderr, " ");
+        }
+        fprintf (stderr, " | ");
+
+        for (i = 0; i < 16; i++)
+            if ((j + i) < buffer.size() && ::isprint(buffer[j+i]))
+                fprintf (stderr, "%c", buffer[j+i]);
+            else
+                fprintf (stderr, ".");
+        fprintf (stderr, "\n");
+    }
+}
+
+} // namespace
+
 void StreamSocket::dumpState()
 {
     std::cerr << "\t" << getFD() << "\t" << getPollEvents() << "\t"
               << _inBuffer.size() << "\t" << _outBuffer.size() << "\t"
               << "\n";
-    // FIXME: hex dump buffer contents if we have them.
+    if (_inBuffer.size() > 0)
+        dump_hex("\t\tinBuffer:\n", "\t\t", _inBuffer);
+    if (_outBuffer.size() > 0)
+        dump_hex("\t\toutBuffer:\n", "\t\t", _inBuffer);
 }
 
 void SocketPoll::dumpState()
commit a7b75e54e980e5159648610f524d8f58e4717bbc
Author: Michael Meeks <michael.me...@collabora.com>
Date:   Mon Mar 6 20:56:40 2017 +0000

    Stage #2

diff --git a/Makefile.am b/Makefile.am
index dd249b7..4c4cce4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -138,7 +138,6 @@ wsd_headers = wsd/Admin.hpp \
               wsd/DocumentBroker.hpp \
               wsd/Exceptions.hpp \
               wsd/FileServer.hpp \
-              wsd/LOOLWebSocket.hpp \
               wsd/LOOLWSD.hpp \
               wsd/QueueHandler.hpp \
               wsd/SenderQueue.hpp \
diff --git a/net/ServerSocket.hpp b/net/ServerSocket.hpp
index 6d86daf..0eca390 100644
--- a/net/ServerSocket.hpp
+++ b/net/ServerSocket.hpp
@@ -27,7 +27,7 @@ public:
 class ServerSocket : public Socket
 {
 public:
-    ServerSocket(SocketPoll& clientPoller, std::unique_ptr<SocketFactory> 
sockFactory) :
+    ServerSocket(SocketPoll& clientPoller, std::shared_ptr<SocketFactory> 
sockFactory) :
         _clientPoller(clientPoller),
         _sockFactory(std::move(sockFactory))
     {
@@ -106,7 +106,7 @@ public:
 
 private:
     SocketPoll& _clientPoller;
-    std::unique_ptr<SocketFactory> _sockFactory;
+    std::shared_ptr<SocketFactory> _sockFactory;
 };
 
 #endif
diff --git a/net/Socket.hpp b/net/Socket.hpp
index e3434bb..346358c 100644
--- a/net/Socket.hpp
+++ b/net/Socket.hpp
@@ -593,6 +593,7 @@ protected:
     // instead of this many friends...
     friend class WebSocketHandler;
     friend class ClientRequestDispatcher;
+    friend class PrisonerRequestDispatcher;
     friend class SimpleResponseClient;
 };
 
diff --git a/net/WebSocketHandler.hpp b/net/WebSocketHandler.hpp
index 4ea2fb7..4c07c56 100644
--- a/net/WebSocketHandler.hpp
+++ b/net/WebSocketHandler.hpp
@@ -42,7 +42,8 @@ public:
     }
 
     /// Upgrades itself to a websocket directly.
-    WebSocketHandler(const std::weak_ptr<StreamSocket>& socket, const 
Poco::Net::HTTPRequest& request) :
+    WebSocketHandler(const std::weak_ptr<StreamSocket>& socket,
+                     const Poco::Net::HTTPRequest& request) :
         _socket(socket),
         _shuttingDown(false),
         _wsState(WSState::HTTP)
diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index fd711a9..fc221d5 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -38,6 +38,7 @@ using namespace LOOLProtocol;
 
 using Poco::JSON::Object;
 
+#if 0
 void ChildProcess::socketProcessor()
 {
     const auto name = "docbrk_ws_" + std::to_string(_pid);
@@ -78,6 +79,7 @@ void ChildProcess::socketProcessor()
         docBroker->childSocketTerminated();
     }
 }
+#endif
 
 namespace
 {
@@ -807,6 +809,7 @@ void DocumentBroker::alertAllUsers(const std::string& msg)
     }
 }
 
+/// Handles input from the prisoner / child kit process
 bool DocumentBroker::handleInput(const std::vector<char>& payload)
 {
     auto message = std::make_shared<Message>(payload.data(), payload.size(), 
Message::Dir::Out);
diff --git a/wsd/DocumentBroker.hpp b/wsd/DocumentBroker.hpp
index c22eb91..bf0dbdb 100644
--- a/wsd/DocumentBroker.hpp
+++ b/wsd/DocumentBroker.hpp
@@ -26,14 +26,15 @@
 
 #include "IoUtil.hpp"
 #include "Log.hpp"
-#include "LOOLWebSocket.hpp"
 #include "TileDesc.hpp"
 #include "Util.hpp"
 #include "net/Socket.hpp"
+#include "net/WebSocketHandler.hpp"
 
 #include "common/SigUtil.hpp"
 
 // Forwards.
+class PrisonerRequestDispatcher;
 class DocumentBroker;
 class StorageBase;
 class TileCache;
@@ -43,15 +44,17 @@ class Message;
 /// to host a document.
 class ChildProcess
 {
+    // FIXME: urk ...
+    friend class PrisonerRequestDispatcher;
 public:
     /// @param pid is the process ID of the child.
     /// @param ws is the control LOOLWebSocket to the child.
-    ChildProcess(const Poco::Process::PID pid, const 
std::shared_ptr<LOOLWebSocket>& ws) :
+    ChildProcess(const Poco::Process::PID pid, const 
std::shared_ptr<StreamSocket>& socket, const Poco::Net::HTTPRequest &request) :
+
         _pid(pid),
-        _ws(ws),
-        _stop(false)
+        _ws(std::make_shared<WebSocketHandler>(socket, request)),
+        _socket(socket)
     {
-        _thread = std::thread([this]() { this->socketProcessor(); });
         LOG_INF("ChildProcess ctor [" << _pid << "].");
     }
 
@@ -68,6 +71,7 @@ public:
 
             // No need for the socket anymore.
             _ws.reset();
+            _socket.reset();
         }
     }
 
@@ -79,7 +83,8 @@ public:
 
     void stop()
     {
-        _stop = true;
+        // FIXME: stop !?
+        LOG_ERR("What do we do for stop?");
         try
         {
             if (isAlive())
@@ -97,9 +102,7 @@ public:
     void close(const bool rude)
     {
         if (_pid < 0)
-        {
             return;
-        }
 
         try
         {
@@ -110,15 +113,7 @@ public:
 
             // Shutdown the socket to break the thread if blocked on it.
             if (_ws)
-            {
                 _ws->shutdown();
-            }
-
-            // Now should be quick to exit the thread; wait.
-            if (_thread.joinable())
-            {
-                _thread.join();
-            }
         }
         catch (const std::exception& ex)
         {
@@ -148,7 +143,7 @@ public:
             if (_ws)
             {
                 LOG_TRC("DocBroker to Child: " << data);
-                _ws->sendFrame(data.data(), data.size());
+                _ws->sendFrame(data);
                 return true;
             }
         }
@@ -170,8 +165,8 @@ public:
     {
         try
         {
-            return (_pid > 1 && _ws && kill(_pid, 0) == 0 &&
-                    !_ws->poll(Poco::Timespan(0), 
Poco::Net::Socket::SelectMode::SELECT_ERROR));
+            return _pid > 1 && _ws && kill(_pid, 0) == 0;
+// FIXME:                    !_ws->poll(Poco::Timespan(0), 
Poco::Net::Socket::SelectMode::SELECT_ERROR));
         }
         catch (const std::exception&)
         {
@@ -185,10 +180,9 @@ private:
 
 private:
     Poco::Process::PID _pid;
-    std::shared_ptr<LOOLWebSocket> _ws;
+    std::shared_ptr<WebSocketHandler> _ws;
+    std::shared_ptr<Socket> _socket;
     std::weak_ptr<DocumentBroker> _docBroker;
-    std::thread _thread;
-    std::atomic<bool> _stop;
 };
 
 class ClientSession;
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index 1c57f81..065afb7 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -560,6 +560,7 @@ public:
     }
 };
 
+#if 0
 /// Handler of announcements that a new loolkit process was created.
 ///
 /// loolforkit is creating the loolkit processes.  That happens
@@ -582,40 +583,6 @@ public:
 
     static void handlePrisonerRequest(HTTPServerRequest& request, 
HTTPServerResponse& response)
     {
-        LOG_TRC("Child connection with URI [" << request.getURI() << "].");
-        assert(request.serverAddress().port() == MasterPortNumber);
-        if (request.getURI().find(NEW_CHILD_URI) != 0)
-        {
-            LOG_ERR("Invalid incoming URI.");
-            return;
-        }
-
-        // New Child is spawned.
-        const auto params = Poco::URI(request.getURI()).getQueryParameters();
-        Poco::Process::PID pid = -1;
-        for (const auto& param : params)
-        {
-            if (param.first == "pid")
-            {
-                pid = std::stoi(param.second);
-            }
-            else if (param.first == "version")
-            {
-                LOOLWSD::LOKitVersion = param.second;
-            }
-        }
-
-        if (pid <= 0)
-        {
-            LOG_ERR("Invalid PID in child URI [" << request.getURI() << "].");
-            return;
-        }
-
-        LOG_INF("New child [" << pid << "].");
-        auto ws = std::make_shared<LOOLWebSocket>(request, response);
-        UnitWSD::get().newChild(ws);
-
-        addNewChild(std::make_shared<ChildProcess>(pid, ws));
     }
 };
 
@@ -642,6 +609,7 @@ public:
         return new PrisonerRequestHandler();
     }
 };
+#endif
 
 namespace
 {
@@ -1630,6 +1598,164 @@ static std::shared_ptr<ClientSession> 
createNewClientSession(const WebSocketHand
     return nullptr;
 }
 
+class PrisonerRequestDispatcher : public WebSocketHandler
+{
+    std::weak_ptr<ChildProcess> _childProcess;
+public:
+    PrisonerRequestDispatcher()
+    {
+    }
+    ~PrisonerRequestDispatcher()
+    {
+        // Notify the broker that we're done.
+        auto child = _childProcess.lock();
+        auto docBroker = child ? child->_docBroker.lock() : nullptr;
+        if (docBroker)
+        {
+            // FIXME: No need to notify if asked to stop.
+            docBroker->childSocketTerminated();
+        }
+    }
+
+private:
+    /// Keep our socket around ...
+    void onConnect(const std::weak_ptr<StreamSocket>& socket) override
+    {
+        LOG_TRC("Prisoner - new socket\n");
+        _socket = socket;
+        LOG_TRC("Prisoner connection disconnected\n");
+    }
+
+    void onDisconnect() override
+    {
+        LOG_TRC("Prisoner connection disconnected\n");
+    }
+
+    /// Called after successful socket reads.
+    void handleIncomingMessage() override
+    {
+        auto socket = _socket.lock();
+        std::vector<char>& in = socket->_inBuffer;
+
+        // Find the end of the header, if any.
+        static const std::string marker("\r\n\r\n");
+        auto itBody = std::search(in.begin(), in.end(),
+                                  marker.begin(), marker.end());
+        if (itBody == in.end())
+        {
+            LOG_TRC("#" << socket->getFD() << " doesn't have enough data 
yet.");
+            return;
+        }
+
+        // Skip the marker.
+        itBody += marker.size();
+
+        Poco::MemoryInputStream message(&in[0], in.size());
+        Poco::Net::HTTPRequest request;
+        try
+        {
+            request.read(message);
+
+            auto logger = Log::info();
+            // logger << "Request from " << request.clientAddress().toString() 
<< ": "
+            logger << "Prisoner request : "
+                   << request.getMethod() << " " << request.getURI() << " "
+                   << request.getVersion();
+
+            for (const auto& it : request)
+            {
+                logger << " / " << it.first << ": " << it.second;
+            }
+
+            logger << Log::end;
+
+            LOG_TRC("Child connection with URI [" << request.getURI() << "].");
+            if (request.getURI().find(NEW_CHILD_URI) != 0)
+            {
+                LOG_ERR("Invalid incoming URI.");
+                return;
+            }
+
+            // New Child is spawned.
+            const auto params = 
Poco::URI(request.getURI()).getQueryParameters();
+            Poco::Process::PID pid = -1;
+            for (const auto& param : params)
+            {
+                if (param.first == "pid")
+                {
+                    pid = std::stoi(param.second);
+                }
+                else if (param.first == "version")
+                {
+                    LOOLWSD::LOKitVersion = param.second;
+                }
+            }
+
+            if (pid <= 0)
+            {
+                LOG_ERR("Invalid PID in child URI [" << request.getURI() << 
"].");
+                return;
+            }
+
+            LOG_INF("New child [" << pid << "].");
+
+            // FIXME:
+            /* if (UnitWSD::get().filterHandleRequest(
+               UnitWSD::TestRequest::Prisoner,
+               request, response))
+               return; */
+
+            in.clear();
+
+            auto child = std::make_shared<ChildProcess>(pid, _socket.lock(), 
request);
+            _childProcess = child; // weak
+            addNewChild(child);
+        }
+        catch (const std::exception& exc)
+        {
+            // Probably don't have enough data just yet.
+            // TODO: timeout if we never get enough.
+            return;
+        }
+    }
+
+    /// Prisoner websocket fun ... (for now)
+    virtual void handleMessage(bool /*fin*/, WSOpCode /* code */, 
std::vector<char> &data)
+    {
+        if (UnitWSD::get().filterChildMessage(data))
+            return;
+
+        auto child = _childProcess.lock();
+        auto docBroker = child ? child->_docBroker.lock() : nullptr;
+        if (docBroker)
+        {
+            // We should never destroy the broker, since
+            // it owns us and will wait on this thread.
+            assert(docBroker.use_count() > 1);
+            docBroker->handleInput(data);
+        }
+
+        LOG_WRN("Child " << child->_pid <<
+                " has no DocumentBroker to handle message: [" <<
+                LOOLProtocol::getAbbreviatedMessage(data) << "].");
+    }
+
+    bool hasQueuedWrites() const override
+    {
+        LOG_TRC("PrisonerRequestDispatcher - asked for queued writes");
+        return false;
+    }
+
+    void performWrites() override
+    {
+        assert (false);
+    }
+
+private:
+    // The socket that owns us (we can't own it).
+    std::weak_ptr<StreamSocket> _socket;
+};
+
 /// Handles incoming connections and dispatches to the appropriate handler.
 class ClientRequestDispatcher : public SocketHandlerInterface
 {
@@ -2381,11 +2507,14 @@ public:
             _webServerThread.join();
     }
 
-    void start(const int port)
+    void startPrisoners(const int port)
     {
-        _acceptPoll.insertNewSocket(findPrisonerServerPort(MasterPortNumber));
+        _prisonerPoll.insertNewSocket(findPrisonerServerPort(port));
         _prisonerThread = std::thread(runPrisonerManager, std::ref(_stop), 
std::ref(_prisonerPoll));
+    }
 
+    void start(const int port)
+    {
         _acceptPoll.insertNewSocket(findServerPort(port));
         _acceptThread = std::thread(runServer, std::ref(_stop), 
std::ref(_acceptPoll));
 
@@ -2411,6 +2540,9 @@ public:
         std::cerr << "Web Server poll:\n";
         _webServerPoll.dumpState();
 
+        std::cerr << "Prisoner poll:\n";
+        _prisonerPoll.dumpState();
+
         std::cerr << "Document Broker polls:\n";
         for (auto &i : DocBrokers)
             i.second->dumpState();
@@ -2485,11 +2617,9 @@ private:
         {
             LOG_FTL("Failed to listen on Prisoner master port (" <<
                     MasterPortNumber << "). Exiting.");
-            return Application::EXIT_SOFTWARE;
+            _exit(Application::EXIT_SOFTWARE);
         }
 
-        int port = MasterPortNumber;
-
         while (!socket)
         {
             ++port;
@@ -2498,7 +2628,7 @@ private:
                                      _prisonerPoll, factory);
         }
 
-        return nullptr;
+        return socket;
     }
 
     std::shared_ptr<ServerSocket> findServerPort(int port)
@@ -2619,12 +2749,12 @@ int LOOLWSD::main(const std::vector<std::string>& 
/*args*/)
     // We provision up to half the limit to connect simultaneously
     // without loss of performance. This cap is to avoid flooding the server.
     static_assert(MAX_CONNECTIONS >= 3, "MAX_CONNECTIONS must be at least 3");
+
+#if 0 // loolnb
     const auto maxThreadCount = MAX_CONNECTIONS * 5;
 
-#if 0
     auto params2 = new HTTPServerParams();
     params2->setMaxThreads(maxThreadCount);
-#endif
 
     // Twice as many min and max since we share this pool
     // between both internal and external connections.
@@ -2632,7 +2762,6 @@ int LOOLWSD::main(const std::vector<std::string>& 
/*args*/)
     const auto idleTimeSeconds = 90;
     const auto stackSizeBytes = 256 * 1024;
 
-#if 0 // loolnb
     ThreadPool threadPool(minThreadCount * 2,
                           maxThreadCount * 2,
                           idleTimeSeconds,
@@ -2656,6 +2785,8 @@ int LOOLWSD::main(const std::vector<std::string>& 
/*args*/)
     srv2.start();
 #endif
 
+    srv.startPrisoners(MasterPortNumber);
+
     // Fire the ForKit process; we are ready to get child connections.
     if (!createForKit())
     {
@@ -2663,7 +2794,6 @@ int LOOLWSD::main(const std::vector<std::string>& 
/*args*/)
         return Application::EXIT_SOFTWARE;
     }
 
-    // TODO loolnb
     srv.start(ClientPortNumber);
 
 #if ENABLE_DEBUG
@@ -2756,8 +2886,10 @@ int LOOLWSD::main(const std::vector<std::string>& 
/*args*/)
 
     // Wait until documents are saved and sessions closed.
     srv.stop();
+#if 0 // loolnb
     srv2.stop();
     threadPool.joinAll();
+#endif
 
     // atexit handlers tend to free Admin before Documents
     LOG_INF("Cleaning up lingering documents.");
@@ -2832,17 +2964,17 @@ int LOOLWSD::main(const std::vector<std::string>& 
/*args*/)
     return returnValue;
 }
 
-void UnitWSD::testHandleRequest(TestRequest type, UnitHTTPServerRequest& 
request, UnitHTTPServerResponse& response)
+void UnitWSD::testHandleRequest(TestRequest type, UnitHTTPServerRequest& /* 
request */, UnitHTTPServerResponse& /* response */)
 {
     switch (type)
     {
     case TestRequest::Client:
 #if 0 // loolnb
         ClientRequestHandler::handleClientRequest(request, response, 
LOOLWSD::GenSessionId());
-#endif
         break;
     case TestRequest::Prisoner:
         PrisonerRequestHandler::handlePrisonerRequest(request, response);
+#endif
         break;
     default:
         assert(false);
commit d7d7a911103c170b8d77fd26b99cd040c6bc38d5
Author: Michael Meeks <michael.me...@collabora.com>
Date:   Mon Mar 6 19:50:06 2017 +0000

    Start #1

diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index eb6a270..1c57f81 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -2348,6 +2348,14 @@ class SslSocketFactory : public SocketFactory
 };
 #endif
 
+class PrisonerSocketFactory : public SocketFactory
+{
+    std::shared_ptr<Socket> create(const int fd) override
+    {
+        return StreamSocket::create<StreamSocket>(fd, 
std::unique_ptr<SocketHandlerInterface>{ new PrisonerRequestDispatcher });
+    }
+};
+
 /// The main server thread.
 ///
 /// Waits for the connections from the loleaflets, and creates the
@@ -2367,25 +2375,27 @@ public:
         stop();
         if (_acceptThread.joinable())
             _acceptThread.join();
+        if (_prisonerThread.joinable())
+            _prisonerThread.join();
         if (_webServerThread.joinable())
             _webServerThread.join();
     }
 
     void start(const int port)
     {
-        std::shared_ptr<ServerSocket> serverSocket = findServerPort(port);
-
-        _acceptPoll.insertNewSocket(serverSocket);
+        _acceptPoll.insertNewSocket(findPrisonerServerPort(MasterPortNumber));
+        _prisonerThread = std::thread(runPrisonerManager, std::ref(_stop), 
std::ref(_prisonerPoll));
 
+        _acceptPoll.insertNewSocket(findServerPort(port));
         _acceptThread = std::thread(runServer, std::ref(_stop), 
std::ref(_acceptPoll));
 
-        // TODO loolnb - we need a documentThread per document
-        _webServerThread = std::thread(runDocument, std::ref(_stop), 
std::ref(_webServerPoll));
+        _webServerThread = std::thread(runWebServer, std::ref(_stop), 
std::ref(_webServerPoll));
     }
 
     void stop()
     {
         _stop = true;
+        SocketPoll::wakeupWorld();
     }
 
     void dumpState()
@@ -2419,6 +2429,10 @@ private:
     SocketPoll _webServerPoll;
     std::thread _webServerThread;
 
+    /// This thread listens for and accepts prisoner kit processes
+    SocketPoll _prisonerPoll;
+    std::thread _prisonerThread;
+
     static void runServer(std::atomic<bool>& stop, SocketPoll& serverPoll) {
         LOG_INF("Starting master server thread.");
         while (!stop && !TerminationFlag && !ShutdownRequestFlag)
@@ -2432,26 +2446,56 @@ private:
         }
     }
 
-    static void runDocument(std::atomic<bool>& stop, SocketPoll& documentPoll) 
{
-        LOG_INF("Starting document thread.");
+    static void runWebServer(std::atomic<bool>& stop, SocketPoll& 
documentPoll) {
+        LOG_INF("Starting web server thread.");
         while (!stop && !TerminationFlag && !ShutdownRequestFlag)
         {
             documentPoll.poll(5000);
         }
     }
 
-    std::shared_ptr<ServerSocket> getServerSocket(const 
Poco::Net::SocketAddress& addr)
+    static void runPrisonerManager(std::atomic<bool>& stop, SocketPoll& 
prisonerPoll) {
+        LOG_INF("Starting document thread.");
+        while (!stop && !TerminationFlag && !ShutdownRequestFlag)
+        {
+            prisonerPoll.poll(5000);
+        }
+    }
+
+    std::shared_ptr<ServerSocket> getServerSocket(const 
Poco::Net::SocketAddress& addr,
+                                                  SocketPoll &poll,
+                                                  
std::shared_ptr<SocketFactory> factory)
     {
-        std::shared_ptr<ServerSocket> serverSocket = 
std::make_shared<ServerSocket>(_webServerPoll,
-#if ENABLE_SSL
-        LOOLWSD::isSSLEnabled() ? std::unique_ptr<SocketFactory>{ new 
SslSocketFactory() } :
-#endif
-                                  std::unique_ptr<SocketFactory>{ new 
PlainSocketFactory() });
+        std::shared_ptr<ServerSocket> serverSocket = 
std::make_shared<ServerSocket>(poll, factory);
 
         if (serverSocket->bind(addr) &&
             serverSocket->listen())
-        {
             return serverSocket;
+
+        return nullptr;
+    }
+
+    std::shared_ptr<ServerSocket> findPrisonerServerPort(int port)
+    {
+        std::shared_ptr<SocketFactory> factory = 
std::make_shared<PrisonerSocketFactory>();
+        std::shared_ptr<ServerSocket> socket = 
getServerSocket(SocketAddress("127.0.0.1", port),
+                                                               _prisonerPoll, 
factory);
+
+        if (!UnitWSD::isUnitTesting() && !socket)
+        {
+            LOG_FTL("Failed to listen on Prisoner master port (" <<
+                    MasterPortNumber << "). Exiting.");
+            return Application::EXIT_SOFTWARE;
+        }
+
+        int port = MasterPortNumber;
+
+        while (!socket)
+        {
+            ++port;
+            LOG_INF("Prisoner port " << (port - 1) << " is busy, trying " << 
port << ".");
+            socket = getServerSocket(SocketAddress("127.0.0.1", port),
+                                     _prisonerPoll, factory);
         }
 
         return nullptr;
@@ -2460,12 +2504,22 @@ private:
     std::shared_ptr<ServerSocket> findServerPort(int port)
     {
         LOG_INF("Trying to listen on client port " << port << ".");
-        std::shared_ptr<ServerSocket> socket = 
getServerSocket(SocketAddress("127.0.0.1", port));
+        std::shared_ptr<SocketFactory> factory;
+#if ENABLE_SSL
+        if (LOOLWSD::isSSLEnabled())
+            factory = std::make_shared<SslSocketFactory>();
+        else
+            factory = std::make_shared<PlainSocketFactory>();
+#endif
+
+        std::shared_ptr<ServerSocket> socket = 
getServerSocket(SocketAddress("127.0.0.1", port),
+                                                               _webServerPoll, 
factory);
         while (!socket)
         {
             ++port;
             LOG_INF("Client port " << (port - 1) << " is busy, trying " << 
port << ".");
-            socket = getServerSocket(SocketAddress("127.0.0.1", port));
+            socket = getServerSocket(SocketAddress("127.0.0.1", port),
+                                     _webServerPoll, factory);
         }
 
         LOG_INF("Listening to client connections on port " << port);
@@ -2567,14 +2621,18 @@ int LOOLWSD::main(const std::vector<std::string>& 
/*args*/)
     static_assert(MAX_CONNECTIONS >= 3, "MAX_CONNECTIONS must be at least 3");
     const auto maxThreadCount = MAX_CONNECTIONS * 5;
 
+#if 0
     auto params2 = new HTTPServerParams();
     params2->setMaxThreads(maxThreadCount);
+#endif
 
     // Twice as many min and max since we share this pool
     // between both internal and external connections.
     const auto minThreadCount = std::max<int>(NumPreSpawnedChildren * 3, 3);
     const auto idleTimeSeconds = 90;
     const auto stackSizeBytes = 256 * 1024;
+
+#if 0 // loolnb
     ThreadPool threadPool(minThreadCount * 2,
                           maxThreadCount * 2,
                           idleTimeSeconds,
@@ -2596,6 +2654,7 @@ int LOOLWSD::main(const std::vector<std::string>& 
/*args*/)
     HTTPServer srv2(new PrisonerRequestHandlerFactory(), threadPool, *psvs2, 
params2);
     LOG_INF("Starting prisoner server listening on " << MasterPortNumber);
     srv2.start();
+#endif
 
     // Fire the ForKit process; we are ready to get child connections.
     if (!createForKit())
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to