xref: /AOO41X/main/ucb/source/ucp/webdav/SerfLockStore.cxx (revision 3edf699282957a8d2e0e344ed73ba96dfb5a45a4)
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