desktop/source/lib/init.cxx |    5 ++
 include/salhelper/timer.hxx |    8 ++++
 salhelper/source/gcc3.map   |    5 ++
 salhelper/source/timer.cxx  |   75 ++++++++++++++++++++++++++++++++++++--------
 4 files changed, 80 insertions(+), 13 deletions(-)

New commits:
commit 79197949d757c40f750406f59e85d6efe02bf584
Author:     Michael Meeks <michael.me...@collabora.com>
AuthorDate: Fri Mar 14 19:29:11 2025 +0000
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Wed Mar 19 10:24:41 2025 +0100

    Timer - shutdown and re-start salhelper::Timer thread.
    
    Necessary for lok background save.
    
    Change-Id: Ib78f67f124dcd5b2a8b50c65ea58a9e1eb894ade
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182931
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index ecfdef498eff..3520bba53a97 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -77,6 +77,7 @@
 #include <rtl/uri.hxx>
 #include <svl/cryptosign.hxx>
 #include <linguistic/misc.hxx>
+#include <salhelper/timer.hxx>
 #include <cppuhelper/bootstrap.hxx>
 #include <comphelper/random.hxx>
 #include <comphelper/base64.hxx>
@@ -3580,11 +3581,15 @@ static int lo_joinThreads(LibreOfficeKit* /* pThis */)
             comphelper::getProcessComponentContext()),
         css::uno::UNO_QUERY_THROW)->flush();
 
+    salhelper::Timer::joinThread();
+
     return 1;
 }
 
 static void lo_startThreads(LibreOfficeKit* /* pThis */)
 {
+    salhelper::Timer::startThread();
+
     auto ucpWebdav = xContext->getServiceManager()->createInstanceWithContext(
         "com.sun.star.ucb.WebDAVManager", xContext);
     auto joinable = dynamic_cast<comphelper::LibreOfficeKit::ThreadJoinable 
*>(ucpWebdav.get());
diff --git a/include/salhelper/timer.hxx b/include/salhelper/timer.hxx
index 8c0ce5d3a2bc..3fa81785aefe 100644
--- a/include/salhelper/timer.hxx
+++ b/include/salhelper/timer.hxx
@@ -177,6 +177,14 @@ public:
      */
     TTimeValue  SAL_CALL getRemainingTime() const;
 
+    /** Internal method to shutdown the timer thread
+     */
+    static void SAL_CALL joinThread();
+
+    /** Internal method to re-start the timer thread if necessary
+     */
+    static void SAL_CALL startThread();
+
 protected:
 
     /** Destructor.
diff --git a/salhelper/source/gcc3.map b/salhelper/source/gcc3.map
index 3d0d90d4aae0..b1bbad779b31 100644
--- a/salhelper/source/gcc3.map
+++ b/salhelper/source/gcc3.map
@@ -131,6 +131,11 @@ LIBO_UDK_3.6 { # symbols available in >= LibO 3.6
             # non-virtual thunk to salhelper::Thread::run()
 } UDK_3.1;
 
+PRIVATE_1.0 {
+        _ZN9salhelper5Timer10joinThreadEv;
+        _ZN9salhelper5Timer11startThreadEv;
+};
+
 # Unique libstdc++ symbols:
 GLIBCXX_3.4 {
     global:
diff --git a/salhelper/source/timer.cxx b/salhelper/source/timer.cxx
index 07510f228cde..7a83149c867c 100644
--- a/salhelper/source/timer.cxx
+++ b/salhelper/source/timer.cxx
@@ -20,16 +20,15 @@
 
 #include <osl/thread.hxx>
 
-#include <condition_variable>
 #include <mutex>
+#include <condition_variable>
 
 using namespace salhelper;
 
 class salhelper::TimerManager final : public osl::Thread
 {
 public:
-    TimerManager();
-
+    TimerManager(salhelper::Timer* &pHead, std::mutex &Lock);
     ~TimerManager();
 
     /// register timer
@@ -48,24 +47,65 @@ protected:
     /// Checking and triggering of a timer event
     void checkForTimeout();
 
-    /// sorted-queue data
-    salhelper::Timer*       m_pHead;
+    salhelper::Timer*           &m_pHead;
     bool m_terminate;
     /// List Protection
-    std::mutex                  m_Lock;
+    std::mutex                  &m_Lock;
     /// Signal the insertion of a timer
     std::condition_variable     m_notEmpty;
 
     /// "Singleton Pattern"
     //static salhelper::TimerManager* m_pManager;
-
 };
 
-namespace
+namespace {
+class TimerManagerImpl final
 {
-    salhelper::TimerManager& getTimerManager()
+    std::mutex m_Lock; // shared lock with each impl. thread
+    salhelper::Timer* m_pHead; // the underlying shared queue
+    std::shared_ptr<TimerManager> m_pImpl;
+
+public:
+    TimerManagerImpl() : m_pHead(nullptr) { }
+
+    void joinThread()
+    {
+        m_pImpl.reset();
+    }
+
+    void startThread()
+    {
+        std::lock_guard Guard(m_Lock);
+        if (m_pHead)
+            ensureThread();
+    }
+
+    std::shared_ptr<TimerManager> ensureThread()
+    {
+        if (!m_pImpl)
+            m_pImpl.reset(new TimerManager(m_pHead, m_Lock));
+        return m_pImpl;
+    }
+
+    void registerTimer(salhelper::Timer* pTimer)
     {
-        static salhelper::TimerManager aManager;
+        ensureThread()->registerTimer(pTimer);
+    }
+
+    void unregisterTimer(salhelper::Timer * pTimer)
+    {
+        ensureThread()->unregisterTimer(pTimer);
+    }
+
+    bool lookupTimer(const salhelper::Timer* pTimer)
+    {
+        return ensureThread()->lookupTimer(pTimer);
+    }
+};
+
+    TimerManagerImpl& getTimerManager()
+    {
+        static TimerManagerImpl aManager;
         return aManager;
     }
 }
@@ -195,6 +235,16 @@ TTimeValue Timer::getRemainingTime() const
     return TTimeValue(secs, nsecs);
 }
 
+void Timer::joinThread()
+{
+    getTimerManager().joinThread();
+}
+
+void Timer::startThread()
+{
+    getTimerManager().startThread();
+}
+
 /** The timer manager cleanup has been removed (no thread is killed anymore),
     so the thread leaks.
 
@@ -205,8 +255,8 @@ TTimeValue Timer::getRemainingTime() const
             when there are no timers anymore !
 **/
 
-TimerManager::TimerManager() :
-    m_pHead(nullptr), m_terminate(false)
+TimerManager::TimerManager(salhelper::Timer* &pHead, std::mutex &Lock) :
+    m_pHead(pHead), m_terminate(false), m_Lock(Lock)
 {
     // start thread
     create();
@@ -387,7 +437,6 @@ void TimerManager::run()
 
         checkForTimeout();
     }
-
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to