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

Henry Castro hcastro at collabora.com
Sat Jan 9 08:26:27 PST 2016


 loolwsd/Common.hpp     |    1 +
 loolwsd/LOOLBroker.cpp |   18 ++++++++++++------
 loolwsd/LOOLKit.cpp    |   30 +++++++++++++++++++++++-------
 3 files changed, 36 insertions(+), 13 deletions(-)

New commits:
commit f3c8ace597023233a04f8d1097c666d7603a1c33
Author: Henry Castro <hcastro at collabora.com>
Date:   Sat Jan 9 12:26:04 2016 -0400

    loolwsd: request abnormal termination

diff --git a/loolwsd/Common.hpp b/loolwsd/Common.hpp
index e90b446..1be1a89 100644
--- a/loolwsd/Common.hpp
+++ b/loolwsd/Common.hpp
@@ -13,6 +13,7 @@
 
 #include <string>
 
+enum class LOOLState { LOOL_STARTING, LOOL_STOPPING, LOOL_ABNORMAL };
 constexpr int DEFAULT_CLIENT_PORT_NUMBER = 9980;
 constexpr int MASTER_PORT_NUMBER = 9981;
 constexpr int INTERVAL_PROBES = 10;
diff --git a/loolwsd/LOOLBroker.cpp b/loolwsd/LOOLBroker.cpp
index 4718182..96d2ea1 100644
--- a/loolwsd/LOOLBroker.cpp
+++ b/loolwsd/LOOLBroker.cpp
@@ -153,6 +153,14 @@ namespace
         if (nftw(source.c_str(), linkOrCopyFunction, 10, FTW_DEPTH) == -1)
             Log::error("linkOrCopy: nftw() failed for '" + source + "'");
     }
+
+    void requestAbnormalTermination(const Process::PID aPID)
+    {
+        if (kill(aPID, SIGTERM) != 0)
+        {
+            Log::info("Cannot terminate lokit [" + std::to_string(aPID) + "]");
+        }
+    }
 }
 
 class PipeRunnable: public Runnable
@@ -210,8 +218,8 @@ public:
 
         if (getResponseLine(readerChild, aResponse) < 0)
         {
-            //TODO: Cleanup broken children.
             Log::error("Error reading child response: " + std::to_string(nPID) + ". Clearing cache.");
+            requestAbnormalTermination(nPID);
             _cacheURL.clear();
             return false;
         }
@@ -279,8 +287,8 @@ public:
             ssize_t nBytes = Util::writeFIFO(it.second, aMessage.c_str(), aMessage.length());
             if ( nBytes < 0 )
             {
-                //TODO: Cleanup broken children.
                 Log::error("Error writting to child pipe: " + std::to_string(it.first) + ". Clearing cache.");
+                requestAbnormalTermination(it.first);
                 _cacheURL.clear();
                 break;
             }
@@ -290,8 +298,8 @@ public:
             Log::trace("Response from kit [" + std::to_string(it.first) + "]: " + aResponse);
             if ( nBytes < 0 )
             {
-                //TODO: Cleanup broken children.
                 Log::error("Error reading child response: " + std::to_string(it.first) + ". Clearing cache.");
+                requestAbnormalTermination(it.first);
                 _cacheURL.clear();
                 break;
             }
@@ -543,10 +551,8 @@ static int createLibreOfficeKit(const bool sharePages, const std::string& loSubP
 
     if ( (nFIFOWriter = open(pipe.c_str(), O_WRONLY)) < 0 )
     {
-        // TODO.  ill process state, that state should force close prison websockets and
-        // kill, currently we have only "stop server state".
         Log::error("Error: failed to open write pipe [" + pipe + "] with kit. Abandoning child.");
-        Poco::Process::requestTermination(child);
+        requestAbnormalTermination(child);
         return -1;
     }
 
diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp
index ff7c3c3..ac7c181 100644
--- a/loolwsd/LOOLKit.cpp
+++ b/loolwsd/LOOLKit.cpp
@@ -59,12 +59,14 @@ using Poco::FastMutex;
 
 const std::string CHILD_URI = "/loolws/child/";
 const std::string LOKIT_BROKER = "/tmp/loolbroker.fifo";
+static LOOLState TerminationState;
 
 namespace
 {
     void handleSignal(int aSignal)
     {
         Log::info() << "Signal received: " << strsignal(aSignal) << Log::end;
+        TerminationState = ( aSignal == SIGTERM ? LOOLState::LOOL_ABNORMAL : LOOLState::LOOL_STOPPING );
         TerminationFlag = true;
     }
 
@@ -341,6 +343,7 @@ public:
     }
 
     const std::string& getSessionId() const { return _sessionId; }
+    std::shared_ptr<WebSocket> getWebSocket() const { return _ws; }
 
     LibreOfficeKitDocument * getLOKitDocument()
     {
@@ -385,10 +388,10 @@ public:
             cs.setTimeout(0);
             HTTPRequest request(HTTPRequest::HTTP_GET, CHILD_URI);
             HTTPResponse response;
-            auto ws = std::make_shared<WebSocket>(cs, request, response);
+            _ws = std::make_shared<WebSocket>(cs, request, response);
 
-            _session.reset(new ChildProcessSession(_sessionId, ws, _loKit, _loKitDocument, _jailId, _onLoad, _onUnload));
-            ws->setReceiveTimeout(0);
+            _session.reset(new ChildProcessSession(_sessionId, _ws, _loKit, _loKitDocument, _jailId, _onLoad, _onUnload));
+            _ws->setReceiveTimeout(0);
 
             // child Jail TID PID
             std::string hello("child " + _jailId + " " +
@@ -406,7 +409,7 @@ public:
             do
             {
                 char buffer[1024];
-                n = ws->receiveFrame(buffer, sizeof(buffer), flags);
+                n = _ws->receiveFrame(buffer, sizeof(buffer), flags);
 
                 if (n > 0 && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE)
                 {
@@ -458,6 +461,7 @@ private:
     volatile bool _stop;
     std::function<void(LibreOfficeKitDocument*, int)> _onLoad;
     std::function<void(int)> _onUnload;
+    std::shared_ptr<WebSocket> _ws;
 };
 
 // A document container.
@@ -483,11 +487,21 @@ public:
     ~Document()
     {
         // Destroy all connections and views.
-        // wait until loolwsd close all websockets
         for (auto aIterator : _connections)
         {
-            if (aIterator.second->isRunning())
-                aIterator.second->join();
+            if (TerminationState == LOOLState::LOOL_ABNORMAL)
+            {
+                // stop all websockets
+                std::shared_ptr<WebSocket> ws = aIterator.second->getWebSocket();
+                if ( ws )
+                    ws->shutdownReceive();
+            }
+            else
+            {
+                // wait until loolwsd close all websockets
+                if (aIterator.second->isRunning())
+                    aIterator.second->join();
+            }
         }
 
         // Get the document to destroy later.
@@ -768,10 +782,12 @@ void lokit_main(const std::string &loSubPath, const std::string& jailId, const s
         Log::error() << exc.name() << ": " << exc.displayText()
                      << (exc.nested() ? " (" + exc.nested()->displayText() + ")" : "")
                      << Log::end;
+        TerminationState = LOOLState::LOOL_ABNORMAL;
     }
     catch (const std::exception& exc)
     {
         Log::error(std::string("Exception: ") + exc.what());
+        TerminationState = LOOLState::LOOL_ABNORMAL;
     }
 
     _documents.clear();


More information about the Libreoffice-commits mailing list