loolwsd/LOOLWSD.cpp              |   64 +++++++++++++++++++++++++++++++++++++--
 loolwsd/MasterProcessSession.cpp |    3 +
 loolwsd/MasterProcessSession.hpp |    6 +++
 loolwsd/test/httpwstest.cpp      |    1 
 4 files changed, 71 insertions(+), 3 deletions(-)

New commits:
commit 129f797c83f65156ebc15559e0150474a7d7d7d9
Author: Tor Lillqvist <t...@collabora.com>
Date:   Tue Mar 22 20:32:21 2016 +0200

    Need to #include <Poco/Net/PrivateKeyPassphraseHandler.h> to avoid warning
    
    Poco/SharedPtr.h: In instantiation of ‘static void 
Poco::ReleasePolicy<C>::release(C*) [with C = 
Poco::Net::PrivateKeyPassphraseHandler]’:
    Poco/SharedPtr.h:130:14:   required from ‘Poco::SharedPtr<C, RC, 
RP>::SharedPtr(C*) [with C = Poco::Net::PrivateKeyPassphraseHandler; RC = 
Poco::ReferenceCounter; RP = 
Poco::ReleasePolicy<Poco::Net::PrivateKeyPassphraseHandler>]’
    
    Poco/SharedPtr.h:70:3: warning: possible problem detected in invocation of 
delete operator: [-Wdelete-incomplete]
        delete pObj;
    
    Poco/SharedPtr.h:66:25: warning: ‘pObj’ has incomplete type
        static void release(C* pObj)
    
    Poco/Net/PrivateKeyFactory.h:30:7: note: forward declaration of ‘class 
Poco::Net::PrivateKeyPassphraseHandler’
        class PrivateKeyPassphraseHandler;

diff --git a/loolwsd/test/httpwstest.cpp b/loolwsd/test/httpwstest.cpp
index ff05066..9b097fd 100644
--- a/loolwsd/test/httpwstest.cpp
+++ b/loolwsd/test/httpwstest.cpp
@@ -14,6 +14,7 @@
 #include <Poco/Net/InvalidCertificateHandler.h>
 #include <Poco/Net/NetException.h>
 #include <Poco/Net/WebSocket.h>
+#include <Poco/Net/PrivateKeyPassphraseHandler.h>
 #include <Poco/Net/Socket.h>
 #include <Poco/Net/SSLManager.h>
 #include <Poco/Path.h>
commit 9d35b956d90c934b37ad4dfe5c0728204e38b25f
Author: Tor Lillqvist <t...@collabora.com>
Date:   Tue Mar 22 20:27:38 2016 +0200

    bccu#1399: Initial code for auto/idle save
    
    Just a skeleton, actual saving not yet implemented. Also, not sure
    the logic when to trigger save is as intended.
    
    Note that no separate timer classes or objects are used. The existing
    watpid/sleep loop that wakes up once every two seconds currently is
    used. If that loop is re-factored to be less silly, the auto/idle save code
    must be implemented differently.

diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index 430f406..1f7789d 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -49,14 +49,17 @@ DEALINGS IN THE SOFTWARE.
 #include <sys/prctl.h>
 
 #include <ftw.h>
+#include <time.h>
 #include <utime.h>
 
 #include <cassert>
 #include <cstdlib>
 #include <cstring>
 #include <iostream>
+#include <map>
 #include <mutex>
 #include <sstream>
+#include <unordered_set>
 
 #include <Poco/DOM/AutoPtr.h>
 #include <Poco/DOM/DOMParser.h>
@@ -174,6 +177,9 @@ using Poco::XML::NodeList;
 static std::map<std::string, std::shared_ptr<DocumentBroker>> docBrokers;
 static std::mutex docBrokersMutex;
 
+static std::unordered_set<std::shared_ptr<MasterProcessSession>> sessions;
+static std::mutex sessionsMutex;
+
 /// Handles the filename part of the convert-to POST request payload.
 class ConvertToPartHandler : public PartHandler
 {
@@ -551,7 +557,7 @@ private:
 
         // This lock could become a bottleneck.
         // In that case, we can use a pool and index by publicPath.
-        std::unique_lock<std::mutex> lock(docBrokersMutex);
+        std::unique_lock<std::mutex> docBrokersLock(docBrokersMutex);
 
         // Lookup this document.
         auto it = docBrokers.find(docKey);
@@ -572,7 +578,12 @@ private:
         auto ws = std::make_shared<WebSocket>(request, response);
         auto session = std::make_shared<MasterProcessSession>(id, 
LOOLSession::Kind::ToClient, ws, docBroker);
         docBroker->incSessions();
-        lock.unlock();
+        docBrokersLock.unlock();
+
+        std::unique_lock<std::mutex> sessionsLock(sessionsMutex);
+        sessions.insert(session);
+        Log::debug("sessions++: " + std::to_string(sessions.size()));
+        sessionsLock.unlock();
 
         // Request a kit process for this doc.
         const std::string aMessage = "request " + id + " " + docKey + "\r\n";
@@ -597,6 +608,7 @@ private:
                 // The fix is to push everything into the queue
                 // (i.e. change MessageQueue to vector<char>).
                 const std::string firstLine = getFirstLine(data, size);
+                time(&session->lastMessageTime);
                 if (singleLine || firstLine.find("paste") == 0)
                 {
                     if (firstLine.compare(0, 10, "disconnect") == 0) // starts 
with "disconnect"
@@ -625,11 +637,16 @@ private:
             queue.clear();
         }
 
+        sessionsLock.lock();
+        sessions.erase(session);
+        Log::debug("sessions--: " + std::to_string(sessions.size()));
+        sessionsLock.unlock();
+
         Log::info("Finishing GET request handler for session [" + id + "]. 
Joining the queue.");
         queue.put("eof");
         queueHandlerThread.join();
 
-        lock.lock();
+        docBrokersLock.lock();
         if (docBroker->decSessions() == 0)
         {
             Log::debug("Removing DocumentBroker for docKey [" + docKey + "].");
@@ -1317,6 +1334,9 @@ int LOOLWSD::main(const std::vector<std::string>& 
/*args*/)
         waitForTerminationRequest();
     }
 
+    time_t last30SecCheck = time(NULL);
+    time_t lastFiveMinuteCheck = time(NULL);
+
     int status = 0;
     while (!TerminationFlag && !LOOLWSD::DoTest)
     {
@@ -1380,6 +1400,44 @@ int LOOLWSD::main(const std::vector<std::string>& 
/*args*/)
         }
         else // pid == 0, no children have died
         {
+            time_t now = time(NULL);
+            if (now >= last30SecCheck + 30)
+            {
+                Log::debug("30-second check");
+                last30SecCheck = now;
+
+                std::unique_lock<std::mutex> sessionsLock(sessionsMutex);
+                for (auto& it : sessions)
+                {
+                    if (it->lastMessageTime > it->idleSaveTime &&
+                        it->lastMessageTime < now - 30)
+                    {
+                        // Trigger a .uno:Save
+                        Log::info("Idle save triggered for session " + 
it->getId());
+
+                        it->idleSaveTime = now;
+                    }
+                }
+            }
+            if (now >= lastFiveMinuteCheck + 300)
+            {
+                Log::debug("Five-minute check");
+                lastFiveMinuteCheck = now;
+
+                std::unique_lock<std::mutex> sessionsLock(sessionsMutex);
+                for (auto& it : sessions)
+                {
+                    if (it->lastMessageTime >= it->idleSaveTime && 
+                        it->lastMessageTime >= it->autoSaveTime)
+                    {
+                        // Trigger a .uno:Save
+                        Log::info("Auto-save triggered for session " + 
it->getId());
+
+                        it->autoSaveTime = now;
+                    }
+                }
+            }
+
             sleep(MAINTENANCE_INTERVAL*2);
         }
     }
diff --git a/loolwsd/MasterProcessSession.cpp b/loolwsd/MasterProcessSession.cpp
index 98941b3..52c8b81 100644
--- a/loolwsd/MasterProcessSession.cpp
+++ b/loolwsd/MasterProcessSession.cpp
@@ -35,6 +35,9 @@ MasterProcessSession::MasterProcessSession(const std::string& 
id,
                                            
std::shared_ptr<Poco::Net::WebSocket> ws,
                                            std::shared_ptr<DocumentBroker> 
docBroker) :
     LOOLSession(id, kind, ws),
+    lastMessageTime(0),
+    idleSaveTime(0),
+    autoSaveTime(0),
     _curPart(0),
     _loadPart(-1),
     _docBroker(docBroker)
diff --git a/loolwsd/MasterProcessSession.hpp b/loolwsd/MasterProcessSession.hpp
index f102760..7b0b0cb 100644
--- a/loolwsd/MasterProcessSession.hpp
+++ b/loolwsd/MasterProcessSession.hpp
@@ -10,6 +10,8 @@
 #ifndef INCLUDED_MASTERPROCESSSESSION_HPP
 #define INCLUDED_MASTERPROCESSSESSION_HPP
 
+#include <time.h>
+
 #include <Poco/Random.h>
 
 #include "DocumentBroker.hpp"
@@ -48,6 +50,10 @@ class MasterProcessSession final : public LOOLSession, 
public std::enable_shared
     static std::mutex AvailableChildSessionMutex;
     static std::condition_variable AvailableChildSessionCV;
 
+    time_t lastMessageTime;
+    time_t idleSaveTime;
+    time_t autoSaveTime;
+
  protected:
     bool invalidateTiles(const char *buffer, int length, 
Poco::StringTokenizer& tokens);
 
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to