From 3648ba0db379b3ca2cc6bb84a4b6c14f16217fa9 Mon Sep 17 00:00:00 2001 From: Matúš Kukan Date: Thu, 20 Mar 2014 12:27:21 +0100 Subject: webdav: Store locks in SerfLockStore, so we could unlock later. Change-Id: If2667e9374917dd1e4c4361378783729761e7dda --- ucb/Library_ucpdav1.mk | 2 +- ucb/source/ucp/webdav/AprEnv.cxx | 9 ++++ ucb/source/ucp/webdav/AprEnv.hxx | 6 +++ ucb/source/ucp/webdav/SerfLockReqProcImpl.cxx | 24 +++++++++- ucb/source/ucp/webdav/SerfLockReqProcImpl.hxx | 4 ++ ucb/source/ucp/webdav/SerfLockStore.cxx | 64 +++++++------------------- ucb/source/ucp/webdav/SerfLockStore.hxx | 53 +++++++++------------ ucb/source/ucp/webdav/SerfRequestProcessor.cxx | 1 + ucb/source/ucp/webdav/SerfSession.cxx | 10 +--- ucb/source/ucp/webdav/SerfSession.hxx | 7 +-- ucb/source/ucp/webdav/SerfTypes.hxx | 3 -- 11 files changed, 87 insertions(+), 96 deletions(-) diff --git a/ucb/Library_ucpdav1.mk b/ucb/Library_ucpdav1.mk index ad0fe79fae33..9ada038bb02d 100644 --- a/ucb/Library_ucpdav1.mk +++ b/ucb/Library_ucpdav1.mk @@ -85,6 +85,7 @@ $(eval $(call gb_Library_add_exception_objects,ucpdav1,\ ucb/source/ucp/webdav/SerfHeadReqProcImpl \ ucb/source/ucp/webdav/SerfInputStream \ ucb/source/ucp/webdav/SerfLockReqProcImpl \ + ucb/source/ucp/webdav/SerfLockStore \ ucb/source/ucp/webdav/SerfMkColReqProcImpl \ ucb/source/ucp/webdav/SerfMoveReqProcImpl \ ucb/source/ucp/webdav/SerfPostReqProcImpl \ @@ -104,7 +105,6 @@ $(eval $(call gb_Library_add_exception_objects,ucpdav1,\ ucb/source/ucp/webdav/webdavresultset \ ucb/source/ucp/webdav/webdavservices \ )) - #ucb/source/ucp/webdav/SerfLockStore endif # WITH_WEBDAV diff --git a/ucb/source/ucp/webdav/AprEnv.cxx b/ucb/source/ucp/webdav/AprEnv.cxx index 327b7dd82ad1..e9e650f8c7a7 100644 --- a/ucb/source/ucp/webdav/AprEnv.cxx +++ b/ucb/source/ucp/webdav/AprEnv.cxx @@ -28,10 +28,14 @@ AprEnv::AprEnv() apr_initialize(); apr_pool_create(&mpAprPool, NULL); + + mpSerfLockStore = new http_dav_ucp::SerfLockStore(); } AprEnv::~AprEnv() { + delete mpSerfLockStore; + apr_pool_destroy(mpAprPool); apr_terminate(); @@ -50,6 +54,11 @@ apr_pool_t* AprEnv::getAprPool() return mpAprPool; } +http_dav_ucp::SerfLockStore* AprEnv::getSerfLockStore() +{ + return mpSerfLockStore; +} + } // namespace apr_environment /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav/AprEnv.hxx b/ucb/source/ucp/webdav/AprEnv.hxx index 9b7c59b074fe..4f360aa2a777 100644 --- a/ucb/source/ucp/webdav/AprEnv.hxx +++ b/ucb/source/ucp/webdav/AprEnv.hxx @@ -22,6 +22,7 @@ #define INCLUDED_APRENV_HXX #include +#include namespace apr_environment { @@ -36,8 +37,13 @@ class AprEnv apr_pool_t* getAprPool(); + http_dav_ucp::SerfLockStore* getSerfLockStore(); + private: apr_pool_t* mpAprPool; + // SerfLockStore is a static object and has to be destroyed + // before AprEnv, so store it here. + http_dav_ucp::SerfLockStore* mpSerfLockStore; AprEnv(); diff --git a/ucb/source/ucp/webdav/SerfLockReqProcImpl.cxx b/ucb/source/ucp/webdav/SerfLockReqProcImpl.cxx index 667583dbf661..9e16212a2f8f 100644 --- a/ucb/source/ucp/webdav/SerfLockReqProcImpl.cxx +++ b/ucb/source/ucp/webdav/SerfLockReqProcImpl.cxx @@ -18,6 +18,9 @@ */ #include "SerfLockReqProcImpl.hxx" + +#include "AprEnv.hxx" +#include "SerfSession.hxx" #include "DAVException.hxx" #include "webdavresponseparser.hxx" @@ -28,8 +31,10 @@ namespace http_dav_ucp SerfLockReqProcImpl::SerfLockReqProcImpl( const char* inPath, const DAVRequestHeaders& inRequestHeaders, + SerfSession& rSession, const css::ucb::Lock & rLock ) : SerfRequestProcessorImpl( inPath, inRequestHeaders ) + , m_rSession( rSession ) , m_aLock( rLock ) , m_xInputStream( new SerfInputStream() ) { @@ -139,7 +144,24 @@ void SerfLockReqProcImpl::handleEndOfResponseData( serf_bucket_t * ) { for (size_t i = 0; i < aLocks.size(); ++i) { - // m_pSerfLockStore->addLock( aLocks[i], m_pSerfSession, m_aStartCall ); + sal_Int64 timeout = aLocks[i].Timeout; + TimeValue aEnd; + osl_getSystemTime( &aEnd ); + // Try to estimate a safe absolute time for sending the + // lock refresh request. + sal_Int32 lastChanceToSendRefreshRequest = -1; + if ( timeout != -1 ) + { + sal_Int32 calltime = aEnd.Seconds - m_aStartCall.Seconds; + if ( calltime <= timeout ) + lastChanceToSendRefreshRequest = aEnd.Seconds + timeout - calltime; + else + SAL_WARN("ucb.ucp.webdav", "No chance to refresh lock before timeout!" ); + } + apr_environment::AprEnv::getAprEnv()->getSerfLockStore()->addLock( + OUString::createFromAscii(getPathStr()), + aLocks[i].LockTokens[0], + &m_rSession, lastChanceToSendRefreshRequest ); SAL_INFO("ucb.ucp.webdav", "SerfSession::LOCK: created lock for " << getPathStr() << ". token: " << aLocks[i].LockTokens[0]); } diff --git a/ucb/source/ucp/webdav/SerfLockReqProcImpl.hxx b/ucb/source/ucp/webdav/SerfLockReqProcImpl.hxx index cb746a30ab16..766bc2ba6c5e 100644 --- a/ucb/source/ucp/webdav/SerfLockReqProcImpl.hxx +++ b/ucb/source/ucp/webdav/SerfLockReqProcImpl.hxx @@ -29,11 +29,14 @@ namespace http_dav_ucp { +class SerfSession; + class SerfLockReqProcImpl : public SerfRequestProcessorImpl { public: SerfLockReqProcImpl( const char* inPath, const DAVRequestHeaders& inRequestHeaders, + SerfSession& rSession, const css::ucb::Lock & rLock ); virtual ~SerfLockReqProcImpl() SAL_OVERRIDE; @@ -48,6 +51,7 @@ private: virtual void handleEndOfResponseData( serf_bucket_t * inSerfResponseBucket ) SAL_OVERRIDE; + SerfSession& m_rSession; css::ucb::Lock m_aLock; TimeValue m_aStartCall; css::uno::Reference< SerfInputStream > m_xInputStream; diff --git a/ucb/source/ucp/webdav/SerfLockStore.cxx b/ucb/source/ucp/webdav/SerfLockStore.cxx index 82468ececf3d..15aae7e50c07 100644 --- a/ucb/source/ucp/webdav/SerfLockStore.cxx +++ b/ucb/source/ucp/webdav/SerfLockStore.cxx @@ -17,8 +17,6 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#include -#include #include #include #include @@ -76,10 +74,8 @@ void TickerThread::run() SerfLockStore::SerfLockStore() - : m_pSerfLockStore( ne_lockstore_create() ), - m_pTickerThread( 0 ) + : m_pTickerThread( 0 ) { - SAL_WARN_IF( !m_pSerfLockStore, "ucb.ucp.webdav", "Unable to create neon lock store!" ); } @@ -95,16 +91,10 @@ SerfLockStore::~SerfLockStore() const LockInfoMap::const_iterator end( m_aLockInfoMap.end() ); while ( it != end ) { - SerfLock * pLock = (*it).first; - (*it).second.xSession->UNLOCK( pLock ); - - ne_lockstore_remove( m_pSerfLockStore, pLock ); - ne_lock_destroy( pLock ); - + const OUString& rLock = (*it).first; + (*it).second.m_xSession->UNLOCK( rLock ); ++it; } - - ne_lockstore_destroy( m_pSerfLockStore ); } @@ -134,62 +124,42 @@ void SerfLockStore::stopTicker() } -void SerfLockStore::registerSession( HttpSession * pHttpSession ) -{ - osl::MutexGuard aGuard( m_aMutex ); - - ne_lockstore_register( m_pSerfLockStore, pHttpSession ); -} - - -SerfLock * SerfLockStore::findByUri( OUString const & rUri ) -{ - osl::MutexGuard aGuard( m_aMutex ); - - ne_uri aUri; - ne_uri_parse( OUStringToOString( - rUri, RTL_TEXTENCODING_UTF8 ).getStr(), &aUri ); - return ne_lockstore_findbyuri( m_pSerfLockStore, &aUri ); -} - - -void SerfLockStore::addLock( SerfLock * pLock, +void SerfLockStore::addLock( const OUString& rLock, + const OUString& sToken, rtl::Reference< SerfSession > const & xSession, sal_Int32 nLastChanceToSendRefreshRequest ) { osl::MutexGuard aGuard( m_aMutex ); - ne_lockstore_add( m_pSerfLockStore, pLock ); - m_aLockInfoMap[ pLock ] - = LockInfo( xSession, nLastChanceToSendRefreshRequest ); + m_aLockInfoMap[ rLock ] + = LockInfo( sToken, xSession, nLastChanceToSendRefreshRequest ); startTicker(); } -void SerfLockStore::updateLock( SerfLock * pLock, +void SerfLockStore::updateLock( const OUString& rLock, sal_Int32 nLastChanceToSendRefreshRequest ) { osl::MutexGuard aGuard( m_aMutex ); - LockInfoMap::iterator it( m_aLockInfoMap.find( pLock ) ); + 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.nLastChanceToSendRefreshRequest + (*it).second.m_nLastChanceToSendRefreshRequest = nLastChanceToSendRefreshRequest; } } -void SerfLockStore::removeLock( SerfLock * pLock ) +void SerfLockStore::removeLock( const OUString& rLock ) { osl::MutexGuard aGuard( m_aMutex ); - m_aLockInfoMap.erase( pLock ); - ne_lockstore_remove( m_pSerfLockStore, pLock ); + m_aLockInfoMap.erase( rLock ); if ( m_aLockInfoMap.empty() ) stopTicker(); @@ -205,27 +175,27 @@ void SerfLockStore::refreshLocks() while ( it != end ) { LockInfo & rInfo = (*it).second; - if ( rInfo.nLastChanceToSendRefreshRequest != -1 ) + if ( rInfo.m_nLastChanceToSendRefreshRequest != -1 ) { // 30 seconds or less remaining until lock expires? TimeValue t1; osl_getSystemTime( &t1 ); - if ( rInfo.nLastChanceToSendRefreshRequest - 30 + if ( rInfo.m_nLastChanceToSendRefreshRequest - 30 <= sal_Int32( t1.Seconds ) ) { // refresh the lock. sal_Int32 nlastChanceToSendRefreshRequest = -1; - if ( rInfo.xSession->LOCK( + if ( rInfo.m_xSession->LOCK( (*it).first, /* out param */ nlastChanceToSendRefreshRequest ) ) { - rInfo.nLastChanceToSendRefreshRequest + rInfo.m_nLastChanceToSendRefreshRequest = nlastChanceToSendRefreshRequest; } else { // refresh failed. stop auto-refresh. - rInfo.nLastChanceToSendRefreshRequest = -1; + rInfo.m_nLastChanceToSendRefreshRequest = -1; } } } diff --git a/ucb/source/ucp/webdav/SerfLockStore.hxx b/ucb/source/ucp/webdav/SerfLockStore.hxx index 4fff5f6a3cd1..92ab19012c30 100644 --- a/ucb/source/ucp/webdav/SerfLockStore.hxx +++ b/ucb/source/ucp/webdav/SerfLockStore.hxx @@ -24,43 +24,37 @@ #include #include #include -#include "SerfTypes.hxx" +#include +#include +#include namespace http_dav_ucp { class TickerThread; -class SerfSession; -struct ltptr +struct LockInfo { - bool operator()( const SerfLock * p1, const SerfLock * p2 ) const - { - return p1 < p2; - } + 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 struct _LockInfo -{ - rtl::Reference< SerfSession > xSession; - sal_Int32 nLastChanceToSendRefreshRequest; - - _LockInfo() - : nLastChanceToSendRefreshRequest( -1 ) {} - - _LockInfo( rtl::Reference< SerfSession > const & _xSession, - sal_Int32 _nLastChanceToSendRefreshRequest ) - : xSession( _xSession ), - nLastChanceToSendRefreshRequest( _nLastChanceToSendRefreshRequest ) {} - -} LockInfo; - -typedef std::map< SerfLock *, LockInfo, ltptr > LockInfoMap; +typedef std::map< OUString, LockInfo > LockInfoMap; class SerfLockStore { osl::Mutex m_aMutex; -// ne_lock_store * m_pSerfLockStore; TickerThread * m_pTickerThread; LockInfoMap m_aLockInfoMap; @@ -68,20 +62,17 @@ public: SerfLockStore(); ~SerfLockStore(); - void registerSession( HttpSession * pHttpSession ); - - SerfLock * findByUri( OUString const & rUri ); - - void addLock( SerfLock * pLock, + 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( SerfLock * pLock, + void updateLock( const OUString& rLock, sal_Int32 nLastChanceToSendRefreshRequest ); - void removeLock( SerfLock * pLock ); + void removeLock( const OUString& rLock ); void refreshLocks(); diff --git a/ucb/source/ucp/webdav/SerfRequestProcessor.cxx b/ucb/source/ucp/webdav/SerfRequestProcessor.cxx index 8a1663bfc2a5..a557781fcce8 100644 --- a/ucb/source/ucp/webdav/SerfRequestProcessor.cxx +++ b/ucb/source/ucp/webdav/SerfRequestProcessor.cxx @@ -314,6 +314,7 @@ bool SerfRequestProcessor::processLock( const css::ucb::Lock & rLock ) { mpProcImpl = new SerfLockReqProcImpl( mPathStr, mrSerfSession.getRequestEnvironment().m_aRequestHeaders, + mrSerfSession, rLock ); return runProcessor() == APR_SUCCESS; diff --git a/ucb/source/ucp/webdav/SerfSession.cxx b/ucb/source/ucp/webdav/SerfSession.cxx index 1c7189f33d6b..7b21f8fb11d9 100644 --- a/ucb/source/ucp/webdav/SerfSession.cxx +++ b/ucb/source/ucp/webdav/SerfSession.cxx @@ -52,12 +52,6 @@ using namespace com::sun::star; using namespace http_dav_ucp; - - -// static members! -//SerfLockStore SerfSession::m_aSerfLockStore; - - // Constructor SerfSession::SerfSession( @@ -1066,7 +1060,7 @@ sal_Int64 SerfSession::LOCK( const OUString & /*inPath*/, // LOCK (refresh existing lock) -bool SerfSession::LOCK( SerfLock * /*pLock*/, +bool SerfSession::LOCK( const OUString& /*rLock*/, sal_Int32 & /*rlastChanceToSendRefreshRequest*/ ) { osl::Guard< osl::Mutex > theGuard( m_aMutex ); @@ -1132,7 +1126,7 @@ void SerfSession::UNLOCK( const OUString & /*inPath*/, // UNLOCK -bool SerfSession::UNLOCK( SerfLock * /*pLock*/ ) +bool SerfSession::UNLOCK( const OUString& /*rLock*/ ) { osl::Guard< osl::Mutex > theGuard( m_aMutex ); diff --git a/ucb/source/ucp/webdav/SerfSession.hxx b/ucb/source/ucp/webdav/SerfSession.hxx index b2642b145a3f..b3dfab7be719 100644 --- a/ucb/source/ucp/webdav/SerfSession.hxx +++ b/ucb/source/ucp/webdav/SerfSession.hxx @@ -27,7 +27,6 @@ #include #include "DAVSession.hxx" #include "SerfTypes.hxx" -//#include "SerfLockStore.hxx" #include "SerfUri.hxx" namespace ucbhelper { class ProxyDecider; } @@ -63,8 +62,6 @@ private: DAVRequestEnvironment m_aEnv; -// static SerfLockStore m_aSerfLockStore; - char* getHostinfo(); bool isSSLNeeded(); @@ -270,11 +267,11 @@ private: const DAVRequestEnvironment & rEnv ); // refresh lock, called by SerfLockStore::refreshLocks - bool LOCK( SerfLock * pLock, + bool LOCK( const OUString& rLock, sal_Int32 & rlastChanceToSendRefreshRequest ); // unlock, called by SerfLockStore::~SerfLockStore - bool UNLOCK( SerfLock * pLock ); + bool UNLOCK( const OUString& rLock ); /* // low level GET implementation, used by public GET implementations diff --git a/ucb/source/ucp/webdav/SerfTypes.hxx b/ucb/source/ucp/webdav/SerfTypes.hxx index b396697be9f7..2393458c8ef4 100644 --- a/ucb/source/ucp/webdav/SerfTypes.hxx +++ b/ucb/source/ucp/webdav/SerfTypes.hxx @@ -26,9 +26,6 @@ typedef serf_connection_t SerfConnection; -// TODO, figure out type of -typedef int SerfLock; - // TODO, check if we need it later on typedef struct { const char *nspace, *name; } SerfPropName; -- cgit