ucb/source/ucp/webdav-curl/CurlSession.cxx   |   12 +++++++--
 ucb/source/ucp/webdav-curl/SerfLockStore.cxx |   36 ++++++++++++++++++++++++---
 ucb/source/ucp/webdav-curl/SerfLockStore.hxx |   17 +++++++++---
 3 files changed, 56 insertions(+), 9 deletions(-)

New commits:
commit ff2bcefa5266ba2b7c4128fdc25245348dee0bd9
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Thu Oct 7 18:30:37 2021 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Mon Nov 1 18:17:41 2021 +0100

    ucb: webdav-curl: try to prevent acquiring a lock that we already have
    
    This was done for webdav-neon in commit
    b4576f3da4d90139fc5140962d13cb91dab98797 but without checking that the
    requested lock isn't "stronger" than the one that was already acquired.
    
    This is currently not a problem because there is only one caller of
    LOCK() and it passes a hard-coded ucb::Lock argument, but not sure if
    that would change in the future, so try to check for it.
    
    Change-Id: I7a703197208979c330212288c323877a326dd7de
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123229
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/ucb/source/ucp/webdav-curl/CurlSession.cxx 
b/ucb/source/ucp/webdav-curl/CurlSession.cxx
index c6ee6ae78a09..371548cff234 100644
--- a/ucb/source/ucp/webdav-curl/CurlSession.cxx
+++ b/ucb/source/ucp/webdav-curl/CurlSession.cxx
@@ -1638,6 +1638,14 @@ auto CurlSession::LOCK(OUString const& rURIReference, 
ucb::Lock /*const*/& rLock
 {
     SAL_INFO("ucb.ucp.webdav.curl", "LOCK: " << rURIReference);
 
+    // FIXME: why is a *global* LockStore keyed by *path*?
+    if (g_Init.LockStore.getLockTokenForURI(rURIReference, rLock))
+    {
+        // already have a lock that covers the requirement
+        // TODO: maybe use DAV:lockdiscovery to ensure it's valid
+        return;
+    }
+
     // note: no m_Mutex lock needed here, only in CurlProcessor::Lock()
 
     // generate XML document for acquiring new LOCK
@@ -1738,8 +1746,8 @@ auto CurlSession::LOCK(OUString const& rURIReference, 
ucb::Lock /*const*/& rLock
 
     for (auto const& rAcquiredLock : acquiredLocks)
     {
-        g_Init.LockStore.addLock(rURIReference, 
rAcquiredLock.first.LockTokens[0], this,
-                                 rAcquiredLock.second);
+        g_Init.LockStore.addLock(rURIReference, rAcquiredLock.first,
+                                 rAcquiredLock.first.LockTokens[0], this, 
rAcquiredLock.second);
         SAL_INFO("ucb.ucp.webdav.curl", "created LOCK for " << rURIReference);
     }
 }
diff --git a/ucb/source/ucp/webdav-curl/SerfLockStore.cxx 
b/ucb/source/ucp/webdav-curl/SerfLockStore.cxx
index ff9eaac816df..cae43864f8e5 100644
--- a/ucb/source/ucp/webdav-curl/SerfLockStore.cxx
+++ b/ucb/source/ucp/webdav-curl/SerfLockStore.cxx
@@ -21,6 +21,9 @@
 #include <sal/log.hxx>
 #include <osl/time.h>
 #include <osl/thread.hxx>
+
+#include <com/sun/star/ucb/LockScope.hpp>
+
 #include "CurlSession.hxx"
 #include "SerfLockStore.hxx"
 
@@ -140,15 +143,42 @@ OUString SerfLockStore::getLockToken( const OUString& 
rLock )
     return OUString();
 }
 
-void SerfLockStore::addLock( const OUString& rLock,
+OUString const*
+SerfLockStore::getLockTokenForURI(OUString const& rURI, css::ucb::Lock const& 
rLock)
+{
+    osl::MutexGuard aGuard( m_aMutex );
+
+    auto const it(m_aLockInfoMap.find(rURI));
+
+    if (it == m_aLockInfoMap.end())
+    {
+        return nullptr;
+    }
+    // 0: EXCLUSIVE 1: SHARED
+    if (it->second.m_Lock.Scope == ucb::LockScope_SHARED && rLock.Scope == 
ucb::LockScope_EXCLUSIVE)
+    {
+        return nullptr;
+    }
+    assert(it->second.m_Lock.Type == rLock.Type); // only WRITE possible
+    if (it->second.m_Lock.Depth < rLock.Depth)
+    {
+        return nullptr;
+    }
+    assert(it->second.m_Lock.Owner == rLock.Owner); // only own locks expected
+    // ignore Timeout ?
+    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 )
 {
     osl::MutexGuard aGuard( m_aMutex );
 
-    m_aLockInfoMap[ rLock ]
-        = LockInfo( sToken, xSession, nLastChanceToSendRefreshRequest );
+    m_aLockInfoMap[ rURI ]
+        = LockInfo(sToken, rLock, xSession, nLastChanceToSendRefreshRequest);
 
     startTicker();
 }
diff --git a/ucb/source/ucp/webdav-curl/SerfLockStore.hxx 
b/ucb/source/ucp/webdav-curl/SerfLockStore.hxx
index 5bfc8c952cca..c7d1499a6e65 100644
--- a/ucb/source/ucp/webdav-curl/SerfLockStore.hxx
+++ b/ucb/source/ucp/webdav-curl/SerfLockStore.hxx
@@ -24,6 +24,8 @@
 #include <osl/mutex.hxx>
 #include <rtl/ref.hxx>
 #include <rtl/ustring.hxx>
+#include <com/sun/star/ucb/Lock.hpp>
+
 #include "CurlSession.hxx"
 
 namespace http_dav_ucp
@@ -34,6 +36,7 @@ class TickerThread;
 struct LockInfo
 {
     OUString m_sToken;
+    css::ucb::Lock m_Lock;
     rtl::Reference<CurlSession> m_xSession;
     sal_Int32 m_nLastChanceToSendRefreshRequest;
 
@@ -41,11 +44,14 @@ struct LockInfo
         : m_nLastChanceToSendRefreshRequest( -1 ) {}
 
     LockInfo( const OUString& sToken,
+              css::ucb::Lock const& rLock,
               rtl::Reference<CurlSession> const & xSession,
               sal_Int32 nLastChanceToSendRefreshRequest )
-    : m_sToken( sToken ),
-      m_xSession( xSession ),
-      m_nLastChanceToSendRefreshRequest( nLastChanceToSendRefreshRequest ) {}
+        : m_sToken(sToken)
+        , m_Lock(rLock)
+        , m_xSession(xSession)
+        , m_nLastChanceToSendRefreshRequest(nLastChanceToSendRefreshRequest)
+    {}
 };
 
 typedef std::map< OUString, LockInfo > LockInfoMap;
@@ -64,7 +70,10 @@ public:
     bool finishing() const;
     OUString getLockToken( const OUString& rLock );
 
-    void addLock( const OUString& rLock,
+    OUString const* getLockTokenForURI(OUString const& rURI, css::ucb::Lock 
const& rLock);
+
+    void addLock( const OUString& rURI,
+                  css::ucb::Lock const& rLock,
                   const OUString& sToken,
                   rtl::Reference<CurlSession> const & xSession,
                   // time in seconds since Jan 1 1970

Reply via email to