summaryrefslogtreecommitdiff
path: root/ucb
diff options
context:
space:
mode:
authorArmin Le Grand (Allotropia) <armin.le.grand@me.com>2021-09-10 17:58:40 +0200
committerArmin Le Grand (Allotropia) <armin.le.grand@me.com>2021-09-10 17:58:40 +0200
commit84977c3c2541bc5baa72e94aa96391fa8e644272 (patch)
treea5bd5481c3424695b8614df2e902296fb556a0a1 /ucb
parentfa6848f5aa5f2f2361d3969515d836ec96fd82c2 (diff)
Reduce time until LOCK refresh 5% for more secure handling
The LOCK refresh sometimes fails due to currently using exactly the timeout returned by the server which describes how long the lock will be held/guaranteed by the server. This leads to a sometimes too close and unnecessary racing condition, in consequence failing the lock refresh and creating an error. So I added to start that request 5% earlier if the timeout is more than 30s which removes the problem. Tested long run with over 24h where the original always stopped at some point. Change-Id: Ie941cd02e107846e4bb1003b0cd67e6e50cf9bbe
Diffstat (limited to 'ucb')
-rw-r--r--ucb/source/ucp/webdav-neon/NeonSession.cxx28
1 files changed, 26 insertions, 2 deletions
diff --git a/ucb/source/ucp/webdav-neon/NeonSession.cxx b/ucb/source/ucp/webdav-neon/NeonSession.cxx
index c1336c07a9c0..7de19fd30803 100644
--- a/ucb/source/ucp/webdav-neon/NeonSession.cxx
+++ b/ucb/source/ucp/webdav-neon/NeonSession.cxx
@@ -1569,6 +1569,19 @@ void NeonSession::LOCK( const OUString & inPath,
if ( theRetVal == NE_OK )
{
+ // independent from what input timeout was sent to the server, the
+ // accepted timeout is now returned in theLock->timeout. This is the
+ // base for preparing the LOCK refresh needed after that time. To not
+ // risk to fail due to asking too late, add a 5% security margin and
+ // just request the refresh a little bit earlier, to compensate slight
+ // timing losses/changes/errors in the complete data transfer chain.
+ // Cases where this happens just very tight in the time limit have been
+ // recorded.
+ if(theLock->timeout > 30)
+ {
+ theLock->timeout = static_cast<int>(static_cast<double>(theLock->timeout) * 0.95);
+ }
+
m_aNeonLockStore.addLock( theLock,
this,
lastChanceToSendRefreshRequest(
@@ -1614,10 +1627,16 @@ bool NeonSession::LOCK( NeonLock * pLock,
const int theRetVal = ne_lock_refresh(m_pHttpSession, pLock);
if (theRetVal == NE_OK)
{
+ // see above: Add 5% timeout safety to the new timeout returned from the Server
+ if(pLock->timeout > 30)
+ {
+ pLock->timeout = static_cast<int>(static_cast<double>(pLock->timeout) * 0.95);
+ }
+
rlastChanceToSendRefreshRequest
= lastChanceToSendRefreshRequest( startCall, pLock->timeout );
- SAL_INFO( "ucb.ucp.webdav", "LOCK (refresh) - Lock successfully refreshed." );
+ SAL_INFO( "ucb.ucp.webdav", "LOCK (refresh) - Lock successfully refreshed (timeout:" << pLock->timeout << " sec.)" );
return true;
}
else
@@ -1631,8 +1650,13 @@ bool NeonSession::LOCK( NeonLock * pLock,
{
// tdf#126279: see handling of NE_AUTH in HandleError
m_bNeedNewSession = true;
- m_aNeonLockStore.removeLockDeferred(pLock);
}
+
+ // if NeonSession::LOCK initially worked, m_aNeonLockStore.addLock
+ // was executed. So, remove it here - independent from the type of
+ // error -> or short, in any error case
+ m_aNeonLockStore.removeLockDeferred(pLock);
+
return false;
}
}