ucb/source/ucp/webdav-neon/NeonSession.cxx | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-)
New commits: commit 84977c3c2541bc5baa72e94aa96391fa8e644272 Author: Armin Le Grand (Allotropia) <armin.le.gr...@me.com> AuthorDate: Fri Sep 10 17:58:40 2021 +0200 Commit: Armin Le Grand (Allotropia) <armin.le.gr...@me.com> CommitDate: Fri Sep 10 17:58:40 2021 +0200 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 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; } }