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: */