18590a0fdSAndre Fischer /**************************************************************
28590a0fdSAndre Fischer *
38590a0fdSAndre Fischer * Licensed to the Apache Software Foundation (ASF) under one
48590a0fdSAndre Fischer * or more contributor license agreements. See the NOTICE file
58590a0fdSAndre Fischer * distributed with this work for additional information
68590a0fdSAndre Fischer * regarding copyright ownership. The ASF licenses this file
78590a0fdSAndre Fischer * to you under the Apache License, Version 2.0 (the
88590a0fdSAndre Fischer * "License"); you may not use this file except in compliance
98590a0fdSAndre Fischer * with the License. You may obtain a copy of the License at
108590a0fdSAndre Fischer *
118590a0fdSAndre Fischer * http://www.apache.org/licenses/LICENSE-2.0
128590a0fdSAndre Fischer *
138590a0fdSAndre Fischer * Unless required by applicable law or agreed to in writing,
148590a0fdSAndre Fischer * software distributed under the License is distributed on an
158590a0fdSAndre Fischer * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
168590a0fdSAndre Fischer * KIND, either express or implied. See the License for the
178590a0fdSAndre Fischer * specific language governing permissions and limitations
188590a0fdSAndre Fischer * under the License.
198590a0fdSAndre Fischer *
208590a0fdSAndre Fischer *************************************************************/
218590a0fdSAndre Fischer
228590a0fdSAndre Fischer
238590a0fdSAndre Fischer
248590a0fdSAndre Fischer // MARKER(update_precomp.py): autogen include statement, do not remove
258590a0fdSAndre Fischer #include "precompiled_ucb.hxx"
268590a0fdSAndre Fischer
27c1c10f68SAriel Constenla-Haile #include <rtl/ustring.hxx>
28c1c10f68SAriel Constenla-Haile #include <osl/time.h>
29c1c10f68SAriel Constenla-Haile #include <osl/thread.hxx>
30*3edf6992SAndrea Pescetti #include "SerfTypes.hxx"
318590a0fdSAndre Fischer #include "SerfSession.hxx"
328590a0fdSAndre Fischer #include "SerfLockStore.hxx"
338590a0fdSAndre Fischer
348590a0fdSAndre Fischer using namespace http_dav_ucp;
358590a0fdSAndre Fischer
368590a0fdSAndre Fischer namespace http_dav_ucp {
378590a0fdSAndre Fischer
388590a0fdSAndre Fischer class TickerThread : public osl::Thread
398590a0fdSAndre Fischer {
408590a0fdSAndre Fischer bool m_bFinish;
418590a0fdSAndre Fischer SerfLockStore & m_rLockStore;
428590a0fdSAndre Fischer
438590a0fdSAndre Fischer public:
448590a0fdSAndre Fischer
TickerThread(SerfLockStore & rLockStore)458590a0fdSAndre Fischer TickerThread( SerfLockStore & rLockStore )
468590a0fdSAndre Fischer : osl::Thread(), m_bFinish( false ), m_rLockStore( rLockStore ) {}
478590a0fdSAndre Fischer
finish()488590a0fdSAndre Fischer void finish() { m_bFinish = true; }
498590a0fdSAndre Fischer
508590a0fdSAndre Fischer protected:
518590a0fdSAndre Fischer
528590a0fdSAndre Fischer virtual void SAL_CALL run();
538590a0fdSAndre Fischer };
548590a0fdSAndre Fischer
558590a0fdSAndre Fischer } // namespace http_dav_ucp
568590a0fdSAndre Fischer
578590a0fdSAndre Fischer // -------------------------------------------------------------------
run()588590a0fdSAndre Fischer void TickerThread::run()
598590a0fdSAndre Fischer {
60*3edf6992SAndrea Pescetti OSL_TRACE( "TickerThread::run: start." );
618590a0fdSAndre Fischer
628590a0fdSAndre Fischer // we have to go through the loop more often to be able to finish ~quickly
638590a0fdSAndre Fischer const int nNth = 25;
648590a0fdSAndre Fischer
658590a0fdSAndre Fischer int nCount = nNth;
668590a0fdSAndre Fischer while ( !m_bFinish )
678590a0fdSAndre Fischer {
688590a0fdSAndre Fischer if ( nCount-- <= 0 )
698590a0fdSAndre Fischer {
708590a0fdSAndre Fischer m_rLockStore.refreshLocks();
718590a0fdSAndre Fischer nCount = nNth;
728590a0fdSAndre Fischer }
738590a0fdSAndre Fischer
748590a0fdSAndre Fischer TimeValue aTV;
758590a0fdSAndre Fischer aTV.Seconds = 0;
768590a0fdSAndre Fischer aTV.Nanosec = 1000000000 / nNth;
778590a0fdSAndre Fischer wait( aTV );
788590a0fdSAndre Fischer }
798590a0fdSAndre Fischer
808590a0fdSAndre Fischer OSL_TRACE( "TickerThread: stop." );
818590a0fdSAndre Fischer }
828590a0fdSAndre Fischer
838590a0fdSAndre Fischer // -------------------------------------------------------------------
SerfLockStore()848590a0fdSAndre Fischer SerfLockStore::SerfLockStore()
85*3edf6992SAndrea Pescetti : m_pTickerThread( 0 )
868590a0fdSAndre Fischer {
878590a0fdSAndre Fischer }
888590a0fdSAndre Fischer
898590a0fdSAndre Fischer // -------------------------------------------------------------------
~SerfLockStore()908590a0fdSAndre Fischer SerfLockStore::~SerfLockStore()
918590a0fdSAndre Fischer {
928590a0fdSAndre Fischer stopTicker();
938590a0fdSAndre Fischer
948590a0fdSAndre Fischer // release active locks, if any.
958590a0fdSAndre Fischer OSL_ENSURE( m_aLockInfoMap.size() == 0,
968590a0fdSAndre Fischer "SerfLockStore::~SerfLockStore - Releasing active locks!" );
978590a0fdSAndre Fischer
988590a0fdSAndre Fischer LockInfoMap::const_iterator it( m_aLockInfoMap.begin() );
998590a0fdSAndre Fischer const LockInfoMap::const_iterator end( m_aLockInfoMap.end() );
1008590a0fdSAndre Fischer while ( it != end )
1018590a0fdSAndre Fischer {
1028590a0fdSAndre Fischer SerfLock * pLock = (*it).first;
103*3edf6992SAndrea Pescetti try
104*3edf6992SAndrea Pescetti {
1058590a0fdSAndre Fischer (*it).second.xSession->UNLOCK( pLock );
106*3edf6992SAndrea Pescetti (*it).second.xSession->release();
107*3edf6992SAndrea Pescetti }
108*3edf6992SAndrea Pescetti catch (DAVException & )
109*3edf6992SAndrea Pescetti {}
1108590a0fdSAndre Fischer ++it;
1118590a0fdSAndre Fischer }
1128590a0fdSAndre Fischer }
1138590a0fdSAndre Fischer
1148590a0fdSAndre Fischer // -------------------------------------------------------------------
startTicker()1158590a0fdSAndre Fischer void SerfLockStore::startTicker()
1168590a0fdSAndre Fischer {
1178590a0fdSAndre Fischer osl::MutexGuard aGuard( m_aMutex );
1188590a0fdSAndre Fischer
1198590a0fdSAndre Fischer if ( !m_pTickerThread )
1208590a0fdSAndre Fischer {
1218590a0fdSAndre Fischer m_pTickerThread = new TickerThread( *this );
1228590a0fdSAndre Fischer m_pTickerThread->create();
1238590a0fdSAndre Fischer }
1248590a0fdSAndre Fischer }
1258590a0fdSAndre Fischer
1268590a0fdSAndre Fischer // -------------------------------------------------------------------
stopTicker()1278590a0fdSAndre Fischer void SerfLockStore::stopTicker()
1288590a0fdSAndre Fischer {
1298590a0fdSAndre Fischer osl::MutexGuard aGuard( m_aMutex );
1308590a0fdSAndre Fischer
1318590a0fdSAndre Fischer if ( m_pTickerThread )
1328590a0fdSAndre Fischer {
1338590a0fdSAndre Fischer m_pTickerThread->finish();
1348590a0fdSAndre Fischer m_pTickerThread->join();
1358590a0fdSAndre Fischer delete m_pTickerThread;
1368590a0fdSAndre Fischer m_pTickerThread = 0;
1378590a0fdSAndre Fischer }
1388590a0fdSAndre Fischer }
1398590a0fdSAndre Fischer
140*3edf6992SAndrea Pescetti #if 0 //not currently used
1418590a0fdSAndre Fischer // -------------------------------------------------------------------
142*3edf6992SAndrea Pescetti void SerfLockStore::registerSession( SerfSession /* aSession */ )
1438590a0fdSAndre Fischer {
1448590a0fdSAndre Fischer osl::MutexGuard aGuard( m_aMutex );
1458590a0fdSAndre Fischer
1468590a0fdSAndre Fischer }
147*3edf6992SAndrea Pescetti #endif
1488590a0fdSAndre Fischer
1498590a0fdSAndre Fischer // -------------------------------------------------------------------
findByUri(rtl::OUString const & rUri)1508590a0fdSAndre Fischer SerfLock * SerfLockStore::findByUri( rtl::OUString const & rUri)
1518590a0fdSAndre Fischer {
1528590a0fdSAndre Fischer osl::MutexGuard aGuard( m_aMutex );
1538590a0fdSAndre Fischer
154*3edf6992SAndrea Pescetti LockInfoMap::const_iterator it( m_aLockInfoMap.begin() );
155*3edf6992SAndrea Pescetti const LockInfoMap::const_iterator end( m_aLockInfoMap.end() );
156*3edf6992SAndrea Pescetti
157*3edf6992SAndrea Pescetti while ( it != end )
158*3edf6992SAndrea Pescetti {
159*3edf6992SAndrea Pescetti SerfLock * pLock = (*it).first;
160*3edf6992SAndrea Pescetti if( pLock->getResourceUri().equals( rUri ) )
161*3edf6992SAndrea Pescetti {
162*3edf6992SAndrea Pescetti return pLock;
163*3edf6992SAndrea Pescetti }
164*3edf6992SAndrea Pescetti ++it;
165*3edf6992SAndrea Pescetti }
166*3edf6992SAndrea Pescetti
167*3edf6992SAndrea Pescetti return static_cast<SerfLock*>(0);
1688590a0fdSAndre Fischer }
1698590a0fdSAndre Fischer
1708590a0fdSAndre Fischer // -------------------------------------------------------------------
addLock(SerfLock * pLock,rtl::Reference<SerfSession> const & xSession,sal_Int32 nLastChanceToSendRefreshRequest)1718590a0fdSAndre Fischer void SerfLockStore::addLock( SerfLock * pLock,
1728590a0fdSAndre Fischer rtl::Reference< SerfSession > const & xSession,
1738590a0fdSAndre Fischer sal_Int32 nLastChanceToSendRefreshRequest )
1748590a0fdSAndre Fischer {
1758590a0fdSAndre Fischer osl::MutexGuard aGuard( m_aMutex );
1768590a0fdSAndre Fischer
1778590a0fdSAndre Fischer m_aLockInfoMap[ pLock ]
1788590a0fdSAndre Fischer = LockInfo( xSession, nLastChanceToSendRefreshRequest );
179*3edf6992SAndrea Pescetti //acquire this session, needed to manage the lock refresh
180*3edf6992SAndrea Pescetti xSession->acquire();
1818590a0fdSAndre Fischer
182*3edf6992SAndrea Pescetti #if OSL_DEBUG_LEVEL > 0
183*3edf6992SAndrea Pescetti rtl::OUString aOwner;
184*3edf6992SAndrea Pescetti pLock->getLock().Owner >>= aOwner;
185*3edf6992SAndrea Pescetti rtl::OUString aToken;
186*3edf6992SAndrea Pescetti aToken = pLock->getLock().LockTokens[0];
187*3edf6992SAndrea Pescetti OSL_TRACE("SerfLockStore::addLock: new lock added aOwner '%s', token '%s'",
188*3edf6992SAndrea Pescetti rtl::OUStringToOString(aOwner, RTL_TEXTENCODING_UTF8).getStr(),
189*3edf6992SAndrea Pescetti rtl::OUStringToOString(aToken, RTL_TEXTENCODING_UTF8).getStr() );
190*3edf6992SAndrea Pescetti #endif
1918590a0fdSAndre Fischer startTicker();
1928590a0fdSAndre Fischer }
1938590a0fdSAndre Fischer
194*3edf6992SAndrea Pescetti #if 0 //not currently used
1958590a0fdSAndre Fischer // -------------------------------------------------------------------
1968590a0fdSAndre Fischer void SerfLockStore::updateLock( SerfLock * pLock,
1978590a0fdSAndre Fischer sal_Int32 nLastChanceToSendRefreshRequest )
1988590a0fdSAndre Fischer {
1998590a0fdSAndre Fischer osl::MutexGuard aGuard( m_aMutex );
2008590a0fdSAndre Fischer
2018590a0fdSAndre Fischer LockInfoMap::iterator it( m_aLockInfoMap.find( pLock ) );
2028590a0fdSAndre Fischer OSL_ENSURE( it != m_aLockInfoMap.end(),
2038590a0fdSAndre Fischer "SerfLockStore::updateLock: lock not found!" );
2048590a0fdSAndre Fischer
2058590a0fdSAndre Fischer if ( it != m_aLockInfoMap.end() )
2068590a0fdSAndre Fischer {
2078590a0fdSAndre Fischer (*it).second.nLastChanceToSendRefreshRequest
2088590a0fdSAndre Fischer = nLastChanceToSendRefreshRequest;
2098590a0fdSAndre Fischer }
2108590a0fdSAndre Fischer }
211*3edf6992SAndrea Pescetti #endif
2128590a0fdSAndre Fischer
2138590a0fdSAndre Fischer // -------------------------------------------------------------------
removeLock(SerfLock * pLock)2148590a0fdSAndre Fischer void SerfLockStore::removeLock( SerfLock * pLock )
2158590a0fdSAndre Fischer {
2168590a0fdSAndre Fischer osl::MutexGuard aGuard( m_aMutex );
2178590a0fdSAndre Fischer
218*3edf6992SAndrea Pescetti LockInfoMap::iterator it( m_aLockInfoMap.find( pLock ) );
219*3edf6992SAndrea Pescetti if(it != m_aLockInfoMap.end())
220*3edf6992SAndrea Pescetti {
221*3edf6992SAndrea Pescetti LockInfo & rInfo = (*it).second;
222*3edf6992SAndrea Pescetti rInfo.xSession->release();
2238590a0fdSAndre Fischer m_aLockInfoMap.erase( pLock );
224*3edf6992SAndrea Pescetti //the caller should deallocate SerfLock class after the call!
2258590a0fdSAndre Fischer if ( m_aLockInfoMap.size() == 0 )
2268590a0fdSAndre Fischer stopTicker();
2278590a0fdSAndre Fischer }
228*3edf6992SAndrea Pescetti }
2298590a0fdSAndre Fischer
2308590a0fdSAndre Fischer // -------------------------------------------------------------------
refreshLocks()2318590a0fdSAndre Fischer void SerfLockStore::refreshLocks()
2328590a0fdSAndre Fischer {
2338590a0fdSAndre Fischer osl::MutexGuard aGuard( m_aMutex );
2348590a0fdSAndre Fischer
2358590a0fdSAndre Fischer LockInfoMap::iterator it( m_aLockInfoMap.begin() );
2368590a0fdSAndre Fischer const LockInfoMap::const_iterator end( m_aLockInfoMap.end() );
2378590a0fdSAndre Fischer while ( it != end )
2388590a0fdSAndre Fischer {
2398590a0fdSAndre Fischer LockInfo & rInfo = (*it).second;
2408590a0fdSAndre Fischer if ( rInfo.nLastChanceToSendRefreshRequest != -1 )
2418590a0fdSAndre Fischer {
2428590a0fdSAndre Fischer // 30 seconds or less remaining until lock expires?
2438590a0fdSAndre Fischer TimeValue t1;
2448590a0fdSAndre Fischer osl_getSystemTime( &t1 );
2458590a0fdSAndre Fischer if ( rInfo.nLastChanceToSendRefreshRequest - 30
2468590a0fdSAndre Fischer <= sal_Int32( t1.Seconds ) )
2478590a0fdSAndre Fischer {
2488590a0fdSAndre Fischer // refresh the lock.
249*3edf6992SAndrea Pescetti #if OSL_DEBUG_LEVEL > 0
250*3edf6992SAndrea Pescetti ucb::Lock aLock = (*it).first->getLock();
251*3edf6992SAndrea Pescetti rtl::OUString aOwner;
252*3edf6992SAndrea Pescetti aLock.Owner >>= aOwner;
253*3edf6992SAndrea Pescetti rtl::OUString aToken;
254*3edf6992SAndrea Pescetti aToken = aLock.LockTokens[0];
255*3edf6992SAndrea Pescetti OSL_TRACE( "SerfLockStore::refreshLocks: refresh started for lock: aOwner '%s', token '%s'",
256*3edf6992SAndrea Pescetti rtl::OUStringToOString(aOwner, RTL_TEXTENCODING_UTF8).getStr(),
257*3edf6992SAndrea Pescetti rtl::OUStringToOString(aToken, RTL_TEXTENCODING_UTF8).getStr() );
258*3edf6992SAndrea Pescetti #endif
2598590a0fdSAndre Fischer sal_Int32 nlastChanceToSendRefreshRequest = -1;
260*3edf6992SAndrea Pescetti try
2618590a0fdSAndre Fischer {
262*3edf6992SAndrea Pescetti rInfo.xSession->LOCK( (*it).first,
263*3edf6992SAndrea Pescetti /* out param */ nlastChanceToSendRefreshRequest );
2648590a0fdSAndre Fischer rInfo.nLastChanceToSendRefreshRequest
2658590a0fdSAndre Fischer = nlastChanceToSendRefreshRequest;
266*3edf6992SAndrea Pescetti #if OSL_DEBUG_LEVEL > 0
267*3edf6992SAndrea Pescetti OSL_TRACE( "Lock '%s' successfully refreshed." ,
268*3edf6992SAndrea Pescetti rtl::OUStringToOString(aToken, RTL_TEXTENCODING_UTF8).getStr() );
269*3edf6992SAndrea Pescetti #endif
2708590a0fdSAndre Fischer }
271*3edf6992SAndrea Pescetti catch ( DAVException & e )
2728590a0fdSAndre Fischer {
2738590a0fdSAndre Fischer // refresh failed. stop auto-refresh.
274*3edf6992SAndrea Pescetti // TODO i126305 discuss:
275*3edf6992SAndrea Pescetti // probably not a good idea to stop the refresh?
276*3edf6992SAndrea Pescetti // may be just ignore and go on, it's possible the net is temporary down?
2778590a0fdSAndre Fischer rInfo.nLastChanceToSendRefreshRequest = -1;
278*3edf6992SAndrea Pescetti #if OSL_DEBUG_LEVEL > 0
279*3edf6992SAndrea Pescetti OSL_TRACE( "SerfLockStore::refreshLocks: Lock '%s' not refreshed! (error: DAVException.mStatusCode %d)",
280*3edf6992SAndrea Pescetti rtl::OUStringToOString(aToken, RTL_TEXTENCODING_UTF8).getStr(), e.getStatus() );
281*3edf6992SAndrea Pescetti #endif
2828590a0fdSAndre Fischer }
2838590a0fdSAndre Fischer }
2848590a0fdSAndre Fischer }
2858590a0fdSAndre Fischer ++it;
2868590a0fdSAndre Fischer }
2878590a0fdSAndre Fischer }
288