diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2021-09-27 13:09:43 +0200 |
---|---|---|
committer | Michael Stahl <michael.stahl@allotropia.de> | 2021-11-01 18:15:54 +0100 |
commit | a48ccb4c14664e23fbb2c8c1603c82772e5e476e (patch) | |
tree | 39867fbe54cd73b5bb075064103fa248834c6051 /ucb/source/ucp | |
parent | dca684d8f87e766c91de2dec0f9ac0d2822f4217 (diff) |
ucb: copy SerfLockStore class to webdav-curl
Change-Id: If7b12af542a369c0179ff3460f64ece61a63c1ac
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122891
Tested-by: Michael Stahl <michael.stahl@allotropia.de>
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Diffstat (limited to 'ucb/source/ucp')
-rw-r--r-- | ucb/source/ucp/webdav-curl/SerfLockStore.cxx | 218 | ||||
-rw-r--r-- | ucb/source/ucp/webdav-curl/SerfLockStore.hxx | 88 |
2 files changed, 306 insertions, 0 deletions
diff --git a/ucb/source/ucp/webdav-curl/SerfLockStore.cxx b/ucb/source/ucp/webdav-curl/SerfLockStore.cxx new file mode 100644 index 000000000000..ec2f6ae1bea7 --- /dev/null +++ b/ucb/source/ucp/webdav-curl/SerfLockStore.cxx @@ -0,0 +1,218 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <rtl/ustring.hxx> +#include <sal/log.hxx> +#include <osl/time.h> +#include <osl/thread.hxx> +#include "SerfSession.hxx" +#include "SerfLockStore.hxx" + +using namespace http_dav_ucp; + +namespace http_dav_ucp { + +class TickerThread : public osl::Thread +{ + bool m_bFinish; + SerfLockStore & m_rLockStore; + +public: + + explicit TickerThread( SerfLockStore & rLockStore ) + : osl::Thread(), m_bFinish( false ), m_rLockStore( rLockStore ) {} + + void finish() { m_bFinish = true; } + +protected: + + virtual void SAL_CALL run() override; +}; + +} // namespace http_dav_ucp + + +void TickerThread::run() +{ + osl_setThreadName("http_dav_ucp::TickerThread"); + + SAL_INFO("ucb.ucp.webdav", "TickerThread: start." ); + + // 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 ) + { + if ( nCount-- <= 0 ) + { + m_rLockStore.refreshLocks(); + nCount = nNth; + } + + TimeValue aTV; + aTV.Seconds = 0; + aTV.Nanosec = 1000000000 / nNth; + wait( aTV ); + } + + SAL_INFO("ucb.ucp.webdav", "TickerThread: stop." ); +} + + +SerfLockStore::SerfLockStore() + : m_pTickerThread( nullptr ) + , m_bFinishing( false ) +{ +} + + +SerfLockStore::~SerfLockStore() +{ + stopTicker(); + m_bFinishing = true; + + // release active locks, if any. + SAL_WARN_IF( !m_aLockInfoMap.empty(), "ucb.ucp.webdav", + "SerfLockStore::~SerfLockStore - Releasing active locks!" ); + + for ( auto& rLockInfo : m_aLockInfoMap ) + { + rLockInfo.second.m_xSession->UNLOCK( rLockInfo.first ); + } +} + +bool SerfLockStore::finishing() const +{ + return m_bFinishing; +} + +void SerfLockStore::startTicker() +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pTickerThread ) + { + m_pTickerThread = new TickerThread( *this ); + m_pTickerThread->create(); + } +} + + +void SerfLockStore::stopTicker() +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( m_pTickerThread ) + { + m_pTickerThread->finish(); + m_pTickerThread->join(); + delete m_pTickerThread; + m_pTickerThread = nullptr; + } +} + +OUString SerfLockStore::getLockToken( const OUString& rLock ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + LockInfoMap::const_iterator it( m_aLockInfoMap.find( rLock ) ); + if ( it != m_aLockInfoMap.end() ) + return (*it).second.m_sToken; + + SAL_WARN("ucb.ucp.webdav", "SerfLockStore::getLockToken: lock not found!" ); + return OUString(); +} + +void SerfLockStore::addLock( const OUString& rLock, + const OUString& sToken, + rtl::Reference< SerfSession > const & xSession, + sal_Int32 nLastChanceToSendRefreshRequest ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + m_aLockInfoMap[ rLock ] + = LockInfo( sToken, xSession, nLastChanceToSendRefreshRequest ); + + startTicker(); +} + + +void SerfLockStore::updateLock( const OUString& rLock, + sal_Int32 nLastChanceToSendRefreshRequest ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + LockInfoMap::iterator it( m_aLockInfoMap.find( rLock ) ); + SAL_WARN_IF( it == m_aLockInfoMap.end(), "ucb.ucp.webdav", + "SerfLockStore::updateLock: lock not found!" ); + + if ( it != m_aLockInfoMap.end() ) + { + (*it).second.m_nLastChanceToSendRefreshRequest + = nLastChanceToSendRefreshRequest; + } +} + + +void SerfLockStore::removeLock( const OUString& rLock ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + m_aLockInfoMap.erase( rLock ); + + if ( m_aLockInfoMap.empty() ) + stopTicker(); +} + + +void SerfLockStore::refreshLocks() +{ + osl::MutexGuard aGuard( m_aMutex ); + + for ( auto& rLockInfo : m_aLockInfoMap ) + { + LockInfo & rInfo = rLockInfo.second; + 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 ) ) + { + // refresh the lock. + sal_Int32 nlastChanceToSendRefreshRequest = -1; + if ( rInfo.m_xSession->LOCK( + rLockInfo.first, &nlastChanceToSendRefreshRequest ) ) + { + rInfo.m_nLastChanceToSendRefreshRequest + = nlastChanceToSendRefreshRequest; + } + else + { + // refresh failed. stop auto-refresh. + rInfo.m_nLastChanceToSendRefreshRequest = -1; + } + } + } + } +} + +/* 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 new file mode 100644 index 000000000000..5449f049a3ec --- /dev/null +++ b/ucb/source/ucp/webdav-curl/SerfLockStore.hxx @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#pragma once + +#include <map> +#include <osl/mutex.hxx> +#include <rtl/ref.hxx> +#include <rtl/ustring.hxx> +#include "SerfSession.hxx" + +namespace http_dav_ucp +{ + +class TickerThread; + +struct LockInfo +{ + OUString m_sToken; + rtl::Reference< SerfSession > m_xSession; + sal_Int32 m_nLastChanceToSendRefreshRequest; + + LockInfo() + : m_nLastChanceToSendRefreshRequest( -1 ) {} + + LockInfo( const OUString& sToken, + rtl::Reference< SerfSession > const & xSession, + sal_Int32 nLastChanceToSendRefreshRequest ) + : m_sToken( sToken ), + m_xSession( xSession ), + m_nLastChanceToSendRefreshRequest( nLastChanceToSendRefreshRequest ) {} +}; + +typedef std::map< OUString, LockInfo > LockInfoMap; + +class SerfLockStore +{ + osl::Mutex m_aMutex; + TickerThread * m_pTickerThread; + bool m_bFinishing; + LockInfoMap m_aLockInfoMap; + +public: + SerfLockStore(); + ~SerfLockStore(); + + bool finishing() const; + OUString getLockToken( const OUString& rLock ); + + void addLock( const OUString& rLock, + const OUString& sToken, + rtl::Reference< SerfSession > const & xSession, + // time in seconds since Jan 1 1970 + // -1: infinite lock, no refresh + sal_Int32 nLastChanceToSendRefreshRequest ); + + void updateLock( const OUString& rLock, + sal_Int32 nLastChanceToSendRefreshRequest ); + + void removeLock( const OUString& rLock ); + + void refreshLocks(); + +private: + void startTicker(); + void stopTicker(); +}; + +} // namespace http_dav_ucp + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |