1*8590a0fdSAndre Fischer /************************************************************** 2*8590a0fdSAndre Fischer * 3*8590a0fdSAndre Fischer * Licensed to the Apache Software Foundation (ASF) under one 4*8590a0fdSAndre Fischer * or more contributor license agreements. See the NOTICE file 5*8590a0fdSAndre Fischer * distributed with this work for additional information 6*8590a0fdSAndre Fischer * regarding copyright ownership. The ASF licenses this file 7*8590a0fdSAndre Fischer * to you under the Apache License, Version 2.0 (the 8*8590a0fdSAndre Fischer * "License"); you may not use this file except in compliance 9*8590a0fdSAndre Fischer * with the License. You may obtain a copy of the License at 10*8590a0fdSAndre Fischer * 11*8590a0fdSAndre Fischer * http://www.apache.org/licenses/LICENSE-2.0 12*8590a0fdSAndre Fischer * 13*8590a0fdSAndre Fischer * Unless required by applicable law or agreed to in writing, 14*8590a0fdSAndre Fischer * software distributed under the License is distributed on an 15*8590a0fdSAndre Fischer * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*8590a0fdSAndre Fischer * KIND, either express or implied. See the License for the 17*8590a0fdSAndre Fischer * specific language governing permissions and limitations 18*8590a0fdSAndre Fischer * under the License. 19*8590a0fdSAndre Fischer * 20*8590a0fdSAndre Fischer *************************************************************/ 21*8590a0fdSAndre Fischer 22*8590a0fdSAndre Fischer 23*8590a0fdSAndre Fischer 24*8590a0fdSAndre Fischer // MARKER(update_precomp.py): autogen include statement, do not remove 25*8590a0fdSAndre Fischer #include "precompiled_ucb.hxx" 26*8590a0fdSAndre Fischer 27*8590a0fdSAndre Fischer #include <ne_locks.h> 28*8590a0fdSAndre Fischer #include <ne_uri.h> 29*8590a0fdSAndre Fischer #include "rtl/ustring.hxx" 30*8590a0fdSAndre Fischer #include "osl/time.h" 31*8590a0fdSAndre Fischer #include "osl/thread.hxx" 32*8590a0fdSAndre Fischer #include "SerfSession.hxx" 33*8590a0fdSAndre Fischer #include "SerfLockStore.hxx" 34*8590a0fdSAndre Fischer 35*8590a0fdSAndre Fischer using namespace http_dav_ucp; 36*8590a0fdSAndre Fischer 37*8590a0fdSAndre Fischer namespace http_dav_ucp { 38*8590a0fdSAndre Fischer 39*8590a0fdSAndre Fischer class TickerThread : public osl::Thread 40*8590a0fdSAndre Fischer { 41*8590a0fdSAndre Fischer bool m_bFinish; 42*8590a0fdSAndre Fischer SerfLockStore & m_rLockStore; 43*8590a0fdSAndre Fischer 44*8590a0fdSAndre Fischer public: 45*8590a0fdSAndre Fischer 46*8590a0fdSAndre Fischer TickerThread( SerfLockStore & rLockStore ) 47*8590a0fdSAndre Fischer : osl::Thread(), m_bFinish( false ), m_rLockStore( rLockStore ) {} 48*8590a0fdSAndre Fischer 49*8590a0fdSAndre Fischer void finish() { m_bFinish = true; } 50*8590a0fdSAndre Fischer 51*8590a0fdSAndre Fischer protected: 52*8590a0fdSAndre Fischer 53*8590a0fdSAndre Fischer virtual void SAL_CALL run(); 54*8590a0fdSAndre Fischer }; 55*8590a0fdSAndre Fischer 56*8590a0fdSAndre Fischer } // namespace http_dav_ucp 57*8590a0fdSAndre Fischer 58*8590a0fdSAndre Fischer // ------------------------------------------------------------------- 59*8590a0fdSAndre Fischer void TickerThread::run() 60*8590a0fdSAndre Fischer { 61*8590a0fdSAndre Fischer OSL_TRACE( "TickerThread: start." ); 62*8590a0fdSAndre Fischer 63*8590a0fdSAndre Fischer // we have to go through the loop more often to be able to finish ~quickly 64*8590a0fdSAndre Fischer const int nNth = 25; 65*8590a0fdSAndre Fischer 66*8590a0fdSAndre Fischer int nCount = nNth; 67*8590a0fdSAndre Fischer while ( !m_bFinish ) 68*8590a0fdSAndre Fischer { 69*8590a0fdSAndre Fischer if ( nCount-- <= 0 ) 70*8590a0fdSAndre Fischer { 71*8590a0fdSAndre Fischer m_rLockStore.refreshLocks(); 72*8590a0fdSAndre Fischer nCount = nNth; 73*8590a0fdSAndre Fischer } 74*8590a0fdSAndre Fischer 75*8590a0fdSAndre Fischer TimeValue aTV; 76*8590a0fdSAndre Fischer aTV.Seconds = 0; 77*8590a0fdSAndre Fischer aTV.Nanosec = 1000000000 / nNth; 78*8590a0fdSAndre Fischer wait( aTV ); 79*8590a0fdSAndre Fischer } 80*8590a0fdSAndre Fischer 81*8590a0fdSAndre Fischer OSL_TRACE( "TickerThread: stop." ); 82*8590a0fdSAndre Fischer } 83*8590a0fdSAndre Fischer 84*8590a0fdSAndre Fischer // ------------------------------------------------------------------- 85*8590a0fdSAndre Fischer SerfLockStore::SerfLockStore() 86*8590a0fdSAndre Fischer : m_pSerfLockStore( ne_lockstore_create() ), 87*8590a0fdSAndre Fischer m_pTickerThread( 0 ) 88*8590a0fdSAndre Fischer { 89*8590a0fdSAndre Fischer OSL_ENSURE( m_pSerfLockStore, "Unable to create neon lock store!" ); 90*8590a0fdSAndre Fischer } 91*8590a0fdSAndre Fischer 92*8590a0fdSAndre Fischer // ------------------------------------------------------------------- 93*8590a0fdSAndre Fischer SerfLockStore::~SerfLockStore() 94*8590a0fdSAndre Fischer { 95*8590a0fdSAndre Fischer stopTicker(); 96*8590a0fdSAndre Fischer 97*8590a0fdSAndre Fischer // release active locks, if any. 98*8590a0fdSAndre Fischer OSL_ENSURE( m_aLockInfoMap.size() == 0, 99*8590a0fdSAndre Fischer "SerfLockStore::~SerfLockStore - Releasing active locks!" ); 100*8590a0fdSAndre Fischer 101*8590a0fdSAndre Fischer LockInfoMap::const_iterator it( m_aLockInfoMap.begin() ); 102*8590a0fdSAndre Fischer const LockInfoMap::const_iterator end( m_aLockInfoMap.end() ); 103*8590a0fdSAndre Fischer while ( it != end ) 104*8590a0fdSAndre Fischer { 105*8590a0fdSAndre Fischer SerfLock * pLock = (*it).first; 106*8590a0fdSAndre Fischer (*it).second.xSession->UNLOCK( pLock ); 107*8590a0fdSAndre Fischer 108*8590a0fdSAndre Fischer ne_lockstore_remove( m_pSerfLockStore, pLock ); 109*8590a0fdSAndre Fischer ne_lock_destroy( pLock ); 110*8590a0fdSAndre Fischer 111*8590a0fdSAndre Fischer ++it; 112*8590a0fdSAndre Fischer } 113*8590a0fdSAndre Fischer 114*8590a0fdSAndre Fischer ne_lockstore_destroy( m_pSerfLockStore ); 115*8590a0fdSAndre Fischer } 116*8590a0fdSAndre Fischer 117*8590a0fdSAndre Fischer // ------------------------------------------------------------------- 118*8590a0fdSAndre Fischer void SerfLockStore::startTicker() 119*8590a0fdSAndre Fischer { 120*8590a0fdSAndre Fischer osl::MutexGuard aGuard( m_aMutex ); 121*8590a0fdSAndre Fischer 122*8590a0fdSAndre Fischer if ( !m_pTickerThread ) 123*8590a0fdSAndre Fischer { 124*8590a0fdSAndre Fischer m_pTickerThread = new TickerThread( *this ); 125*8590a0fdSAndre Fischer m_pTickerThread->create(); 126*8590a0fdSAndre Fischer } 127*8590a0fdSAndre Fischer } 128*8590a0fdSAndre Fischer 129*8590a0fdSAndre Fischer // ------------------------------------------------------------------- 130*8590a0fdSAndre Fischer void SerfLockStore::stopTicker() 131*8590a0fdSAndre Fischer { 132*8590a0fdSAndre Fischer osl::MutexGuard aGuard( m_aMutex ); 133*8590a0fdSAndre Fischer 134*8590a0fdSAndre Fischer if ( m_pTickerThread ) 135*8590a0fdSAndre Fischer { 136*8590a0fdSAndre Fischer m_pTickerThread->finish(); 137*8590a0fdSAndre Fischer m_pTickerThread->join(); 138*8590a0fdSAndre Fischer delete m_pTickerThread; 139*8590a0fdSAndre Fischer m_pTickerThread = 0; 140*8590a0fdSAndre Fischer } 141*8590a0fdSAndre Fischer } 142*8590a0fdSAndre Fischer 143*8590a0fdSAndre Fischer // ------------------------------------------------------------------- 144*8590a0fdSAndre Fischer void SerfLockStore::registerSession( HttpSession * pHttpSession ) 145*8590a0fdSAndre Fischer { 146*8590a0fdSAndre Fischer osl::MutexGuard aGuard( m_aMutex ); 147*8590a0fdSAndre Fischer 148*8590a0fdSAndre Fischer ne_lockstore_register( m_pSerfLockStore, pHttpSession ); 149*8590a0fdSAndre Fischer } 150*8590a0fdSAndre Fischer 151*8590a0fdSAndre Fischer // ------------------------------------------------------------------- 152*8590a0fdSAndre Fischer SerfLock * SerfLockStore::findByUri( rtl::OUString const & rUri ) 153*8590a0fdSAndre Fischer { 154*8590a0fdSAndre Fischer osl::MutexGuard aGuard( m_aMutex ); 155*8590a0fdSAndre Fischer 156*8590a0fdSAndre Fischer ne_uri aUri; 157*8590a0fdSAndre Fischer ne_uri_parse( rtl::OUStringToOString( 158*8590a0fdSAndre Fischer rUri, RTL_TEXTENCODING_UTF8 ).getStr(), &aUri ); 159*8590a0fdSAndre Fischer return ne_lockstore_findbyuri( m_pSerfLockStore, &aUri ); 160*8590a0fdSAndre Fischer } 161*8590a0fdSAndre Fischer 162*8590a0fdSAndre Fischer // ------------------------------------------------------------------- 163*8590a0fdSAndre Fischer void SerfLockStore::addLock( SerfLock * pLock, 164*8590a0fdSAndre Fischer rtl::Reference< SerfSession > const & xSession, 165*8590a0fdSAndre Fischer sal_Int32 nLastChanceToSendRefreshRequest ) 166*8590a0fdSAndre Fischer { 167*8590a0fdSAndre Fischer osl::MutexGuard aGuard( m_aMutex ); 168*8590a0fdSAndre Fischer 169*8590a0fdSAndre Fischer ne_lockstore_add( m_pSerfLockStore, pLock ); 170*8590a0fdSAndre Fischer m_aLockInfoMap[ pLock ] 171*8590a0fdSAndre Fischer = LockInfo( xSession, nLastChanceToSendRefreshRequest ); 172*8590a0fdSAndre Fischer 173*8590a0fdSAndre Fischer startTicker(); 174*8590a0fdSAndre Fischer } 175*8590a0fdSAndre Fischer 176*8590a0fdSAndre Fischer // ------------------------------------------------------------------- 177*8590a0fdSAndre Fischer void SerfLockStore::updateLock( SerfLock * pLock, 178*8590a0fdSAndre Fischer sal_Int32 nLastChanceToSendRefreshRequest ) 179*8590a0fdSAndre Fischer { 180*8590a0fdSAndre Fischer osl::MutexGuard aGuard( m_aMutex ); 181*8590a0fdSAndre Fischer 182*8590a0fdSAndre Fischer LockInfoMap::iterator it( m_aLockInfoMap.find( pLock ) ); 183*8590a0fdSAndre Fischer OSL_ENSURE( it != m_aLockInfoMap.end(), 184*8590a0fdSAndre Fischer "SerfLockStore::updateLock: lock not found!" ); 185*8590a0fdSAndre Fischer 186*8590a0fdSAndre Fischer if ( it != m_aLockInfoMap.end() ) 187*8590a0fdSAndre Fischer { 188*8590a0fdSAndre Fischer (*it).second.nLastChanceToSendRefreshRequest 189*8590a0fdSAndre Fischer = nLastChanceToSendRefreshRequest; 190*8590a0fdSAndre Fischer } 191*8590a0fdSAndre Fischer } 192*8590a0fdSAndre Fischer 193*8590a0fdSAndre Fischer // ------------------------------------------------------------------- 194*8590a0fdSAndre Fischer void SerfLockStore::removeLock( SerfLock * pLock ) 195*8590a0fdSAndre Fischer { 196*8590a0fdSAndre Fischer osl::MutexGuard aGuard( m_aMutex ); 197*8590a0fdSAndre Fischer 198*8590a0fdSAndre Fischer m_aLockInfoMap.erase( pLock ); 199*8590a0fdSAndre Fischer ne_lockstore_remove( m_pSerfLockStore, pLock ); 200*8590a0fdSAndre Fischer 201*8590a0fdSAndre Fischer if ( m_aLockInfoMap.size() == 0 ) 202*8590a0fdSAndre Fischer stopTicker(); 203*8590a0fdSAndre Fischer } 204*8590a0fdSAndre Fischer 205*8590a0fdSAndre Fischer // ------------------------------------------------------------------- 206*8590a0fdSAndre Fischer void SerfLockStore::refreshLocks() 207*8590a0fdSAndre Fischer { 208*8590a0fdSAndre Fischer osl::MutexGuard aGuard( m_aMutex ); 209*8590a0fdSAndre Fischer 210*8590a0fdSAndre Fischer LockInfoMap::iterator it( m_aLockInfoMap.begin() ); 211*8590a0fdSAndre Fischer const LockInfoMap::const_iterator end( m_aLockInfoMap.end() ); 212*8590a0fdSAndre Fischer while ( it != end ) 213*8590a0fdSAndre Fischer { 214*8590a0fdSAndre Fischer LockInfo & rInfo = (*it).second; 215*8590a0fdSAndre Fischer if ( rInfo.nLastChanceToSendRefreshRequest != -1 ) 216*8590a0fdSAndre Fischer { 217*8590a0fdSAndre Fischer // 30 seconds or less remaining until lock expires? 218*8590a0fdSAndre Fischer TimeValue t1; 219*8590a0fdSAndre Fischer osl_getSystemTime( &t1 ); 220*8590a0fdSAndre Fischer if ( rInfo.nLastChanceToSendRefreshRequest - 30 221*8590a0fdSAndre Fischer <= sal_Int32( t1.Seconds ) ) 222*8590a0fdSAndre Fischer { 223*8590a0fdSAndre Fischer // refresh the lock. 224*8590a0fdSAndre Fischer sal_Int32 nlastChanceToSendRefreshRequest = -1; 225*8590a0fdSAndre Fischer if ( rInfo.xSession->LOCK( 226*8590a0fdSAndre Fischer (*it).first, 227*8590a0fdSAndre Fischer /* out param */ nlastChanceToSendRefreshRequest ) ) 228*8590a0fdSAndre Fischer { 229*8590a0fdSAndre Fischer rInfo.nLastChanceToSendRefreshRequest 230*8590a0fdSAndre Fischer = nlastChanceToSendRefreshRequest; 231*8590a0fdSAndre Fischer } 232*8590a0fdSAndre Fischer else 233*8590a0fdSAndre Fischer { 234*8590a0fdSAndre Fischer // refresh failed. stop auto-refresh. 235*8590a0fdSAndre Fischer rInfo.nLastChanceToSendRefreshRequest = -1; 236*8590a0fdSAndre Fischer } 237*8590a0fdSAndre Fischer } 238*8590a0fdSAndre Fischer } 239*8590a0fdSAndre Fischer ++it; 240*8590a0fdSAndre Fischer } 241*8590a0fdSAndre Fischer } 242