ucb/source/ucp/webdav-curl/SerfLockStore.cxx |   71 +++++++++++++++++----------
 ucb/source/ucp/webdav-curl/SerfLockStore.hxx |    4 +
 2 files changed, 50 insertions(+), 25 deletions(-)

New commits:
commit 867d380b0b8e2c59689eb42665c75aad34733bbc
Author:     Manish Bera <mbera.de...@gmail.com>
AuthorDate: Sun Feb 2 09:56:46 2025 +0530
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Thu Feb 6 10:12:20 2025 +0100

    tdf#161168 Improve constant repetitive loop thread
    
    Change-Id: I01cebb1bb085c3b390c3ced48c431e8f5dc6bcbd
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181005
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/ucb/source/ucp/webdav-curl/SerfLockStore.cxx 
b/ucb/source/ucp/webdav-curl/SerfLockStore.cxx
index cfa6f666b056..b191709a84e1 100644
--- a/ucb/source/ucp/webdav-curl/SerfLockStore.cxx
+++ b/ucb/source/ucp/webdav-curl/SerfLockStore.cxx
@@ -23,6 +23,7 @@
 #include <osl/time.h>
 #include <osl/thread.hxx>
 #include <salhelper/thread.hxx>
+#include <condition_variable>
 
 #include <com/sun/star/ucb/LockScope.hpp>
 #include <thread>
@@ -58,25 +59,28 @@ private:
 void TickerThread::execute()
 {
     osl_setThreadName("http_dav_ucp::TickerThread");
+    SAL_INFO("ucb.ucp.webdav", "TickerThread: start.");
 
-    SAL_INFO("ucb.ucp.webdav",  "TickerThread: start." );
+    std::unique_lock aGuard(m_rLockStore.m_aMutex);
 
-    // we have to go through the loop more often to be able to finish ~quickly
-    const int nNth = 25;
-
-    int nCount = nNth;
-    while ( !m_bFinish )
+    while (!m_bFinish)
     {
-        if ( nCount-- <= 0 )
+        auto sleep_duration = m_rLockStore.refreshLocks(aGuard);
+
+        if (sleep_duration == std::chrono::milliseconds::max())
         {
-            m_rLockStore.refreshLocks();
-            nCount = nNth;
+            // Wait until a lock is added or shutdown
+            m_rLockStore.m_aCondition.wait(
+                aGuard, [this] { return !m_rLockStore.m_aLockInfoMap.empty() 
|| m_bFinish; });
+        }
+        else
+        {
+            // Wait until the next deadline or a notification
+            m_rLockStore.m_aCondition.wait_for(aGuard, sleep_duration);
         }
-
-        std::this_thread::sleep_for( std::chrono::milliseconds(1000/25) );
     }
 
-    SAL_INFO("ucb.ucp.webdav",  "TickerThread: stop." );
+    SAL_INFO("ucb.ucp.webdav", "TickerThread: stop.");
 }
 
 
@@ -185,17 +189,15 @@ SerfLockStore::getLockTokenForURI(OUString const& rURI, 
css::ucb::Lock const*con
     return &it->second.m_sToken;
 }
 
-void SerfLockStore::addLock( const OUString& rURI,
-                             ucb::Lock const& rLock,
-                             const OUString& sToken,
-                             rtl::Reference<CurlSession> const & xSession,
-                             sal_Int32 nLastChanceToSendRefreshRequest )
+void SerfLockStore::addLock(const OUString& rURI, ucb::Lock const& rLock, 
const OUString& sToken,
+                            rtl::Reference<CurlSession> const& xSession,
+                            sal_Int32 nLastChanceToSendRefreshRequest)
 {
     assert(rURI.startsWith("http://";) || rURI.startsWith("https://";));
-    std::unique_lock aGuard( m_aMutex );
+    std::unique_lock aGuard(m_aMutex);
 
-    m_aLockInfoMap[ rURI ]
-        = LockInfo(sToken, rLock, xSession, nLastChanceToSendRefreshRequest);
+    m_aLockInfoMap[rURI] = LockInfo(sToken, rLock, xSession, 
nLastChanceToSendRefreshRequest);
+    m_aCondition.notify_all(); // Wake up the TickerThread
 
     startTicker(aGuard);
 }
@@ -220,11 +222,19 @@ void 
SerfLockStore::removeLockImpl(std::unique_lock<std::mutex> & rGuard, const
     }
 }
 
-void SerfLockStore::refreshLocks()
+std::chrono::milliseconds 
SerfLockStore::refreshLocks(std::unique_lock<std::mutex>&rGuard)
 {
+    assert(rGuard.owns_lock());
+    (void)rGuard;
+
+    TimeValue currentTimeVal;
+    osl_getSystemTime(&currentTimeVal);
+    sal_Int32 currentTime = currentTimeVal.Seconds;
+
     std::unique_lock aGuard( m_aMutex );
 
     ::std::vector<OUString> authFailedLocks;
+    std::chrono::milliseconds min_remaining = std::chrono::milliseconds::max();
 
     for ( auto& rLockInfo : m_aLockInfoMap )
     {
@@ -232,10 +242,8 @@ void SerfLockStore::refreshLocks()
         if ( rInfo.m_nLastChanceToSendRefreshRequest != -1 )
         {
             // 30 seconds or less remaining until lock expires?
-            TimeValue t1;
-            osl_getSystemTime( &t1 );
-            if ( rInfo.m_nLastChanceToSendRefreshRequest - 30
-                     <= sal_Int32( t1.Seconds ) )
+            sal_Int32 deadline = rInfo.m_nLastChanceToSendRefreshRequest - 30;
+            if ( deadline <= currentTime )
             {
                 // refresh the lock.
                 sal_Int32 nlastChanceToSendRefreshRequest = -1;
@@ -258,6 +266,17 @@ void SerfLockStore::refreshLocks()
                     rInfo.m_nLastChanceToSendRefreshRequest = -1;
                 }
             }
+            if (rInfo.m_nLastChanceToSendRefreshRequest != -1)
+            {
+                sal_Int32 remaining = (rInfo.m_nLastChanceToSendRefreshRequest 
- 30) - currentTime;
+                if (remaining > 0)
+                {
+                    auto remaining_ms = std::chrono::seconds(remaining);
+                    if ( remaining_ms < min_remaining )
+                        min_remaining
+                            = 
std::chrono::duration_cast<std::chrono::milliseconds>(remaining_ms);
+                }
+            }
         }
     }
 
@@ -265,6 +284,8 @@ void SerfLockStore::refreshLocks()
     {
         removeLockImpl(aGuard, rLock);
     }
+
+    return min_remaining;
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/ucb/source/ucp/webdav-curl/SerfLockStore.hxx 
b/ucb/source/ucp/webdav-curl/SerfLockStore.hxx
index 30c7fe1d407e..0be90eaac8be 100644
--- a/ucb/source/ucp/webdav-curl/SerfLockStore.hxx
+++ b/ucb/source/ucp/webdav-curl/SerfLockStore.hxx
@@ -27,6 +27,7 @@
 #include <com/sun/star/ucb/Lock.hpp>
 #include <utility>
 #include <comphelper/lok.hxx>
+#include <condition_variable>
 
 #include "CurlSession.hxx"
 
@@ -60,7 +61,10 @@ typedef std::map< OUString, LockInfo > LockInfoMap;
 
 class SerfLockStore : public comphelper::LibreOfficeKit::ThreadJoinable
 {
+public:
     std::mutex         m_aMutex;
+    std::condition_variable m_aCondition;
+    std::chrono::milliseconds refreshLocks(std::unique_lock<std::mutex>& 
rGuard);
     rtl::Reference< TickerThread > m_pTickerThread;
     LockInfoMap        m_aLockInfoMap;
 

Reply via email to