1*51ba086bSDamjan Jovanovic /**************************************************************
2*51ba086bSDamjan Jovanovic *
3*51ba086bSDamjan Jovanovic * Licensed to the Apache Software Foundation (ASF) under one
4*51ba086bSDamjan Jovanovic * or more contributor license agreements. See the NOTICE file
5*51ba086bSDamjan Jovanovic * distributed with this work for additional information
6*51ba086bSDamjan Jovanovic * regarding copyright ownership. The ASF licenses this file
7*51ba086bSDamjan Jovanovic * to you under the Apache License, Version 2.0 (the
8*51ba086bSDamjan Jovanovic * "License"); you may not use this file except in compliance
9*51ba086bSDamjan Jovanovic * with the License. You may obtain a copy of the License at
10*51ba086bSDamjan Jovanovic *
11*51ba086bSDamjan Jovanovic * http://www.apache.org/licenses/LICENSE-2.0
12*51ba086bSDamjan Jovanovic *
13*51ba086bSDamjan Jovanovic * Unless required by applicable law or agreed to in writing,
14*51ba086bSDamjan Jovanovic * software distributed under the License is distributed on an
15*51ba086bSDamjan Jovanovic * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*51ba086bSDamjan Jovanovic * KIND, either express or implied. See the License for the
17*51ba086bSDamjan Jovanovic * specific language governing permissions and limitations
18*51ba086bSDamjan Jovanovic * under the License.
19*51ba086bSDamjan Jovanovic *
20*51ba086bSDamjan Jovanovic *************************************************************/
21*51ba086bSDamjan Jovanovic
22*51ba086bSDamjan Jovanovic
23*51ba086bSDamjan Jovanovic
24*51ba086bSDamjan Jovanovic // MARKER(update_precomp.py): autogen include statement, do not remove
25*51ba086bSDamjan Jovanovic #include "precompiled_webdav.hxx"
26*51ba086bSDamjan Jovanovic
27*51ba086bSDamjan Jovanovic #include <rtl/ustring.hxx>
28*51ba086bSDamjan Jovanovic #include <osl/time.h>
29*51ba086bSDamjan Jovanovic #include <osl/thread.hxx>
30*51ba086bSDamjan Jovanovic #include "CurlTypes.hxx"
31*51ba086bSDamjan Jovanovic #include "CurlSession.hxx"
32*51ba086bSDamjan Jovanovic #include "CurlLockStore.hxx"
33*51ba086bSDamjan Jovanovic
34*51ba086bSDamjan Jovanovic using namespace http_dav_ucp;
35*51ba086bSDamjan Jovanovic
36*51ba086bSDamjan Jovanovic namespace http_dav_ucp {
37*51ba086bSDamjan Jovanovic
38*51ba086bSDamjan Jovanovic class TickerThread : public osl::Thread
39*51ba086bSDamjan Jovanovic {
40*51ba086bSDamjan Jovanovic bool m_bFinish;
41*51ba086bSDamjan Jovanovic CurlLockStore & m_rLockStore;
42*51ba086bSDamjan Jovanovic
43*51ba086bSDamjan Jovanovic public:
44*51ba086bSDamjan Jovanovic
TickerThread(CurlLockStore & rLockStore)45*51ba086bSDamjan Jovanovic TickerThread( CurlLockStore & rLockStore )
46*51ba086bSDamjan Jovanovic : osl::Thread(), m_bFinish( false ), m_rLockStore( rLockStore ) {}
47*51ba086bSDamjan Jovanovic
finish()48*51ba086bSDamjan Jovanovic void finish() { m_bFinish = true; }
49*51ba086bSDamjan Jovanovic
50*51ba086bSDamjan Jovanovic protected:
51*51ba086bSDamjan Jovanovic
52*51ba086bSDamjan Jovanovic virtual void SAL_CALL run();
53*51ba086bSDamjan Jovanovic };
54*51ba086bSDamjan Jovanovic
55*51ba086bSDamjan Jovanovic } // namespace http_dav_ucp
56*51ba086bSDamjan Jovanovic
57*51ba086bSDamjan Jovanovic // -------------------------------------------------------------------
run()58*51ba086bSDamjan Jovanovic void TickerThread::run()
59*51ba086bSDamjan Jovanovic {
60*51ba086bSDamjan Jovanovic OSL_TRACE( "TickerThread::run: start." );
61*51ba086bSDamjan Jovanovic
62*51ba086bSDamjan Jovanovic // we have to go through the loop more often to be able to finish ~quickly
63*51ba086bSDamjan Jovanovic const int nNth = 25;
64*51ba086bSDamjan Jovanovic
65*51ba086bSDamjan Jovanovic int nCount = nNth;
66*51ba086bSDamjan Jovanovic while ( !m_bFinish )
67*51ba086bSDamjan Jovanovic {
68*51ba086bSDamjan Jovanovic if ( nCount-- <= 0 )
69*51ba086bSDamjan Jovanovic {
70*51ba086bSDamjan Jovanovic m_rLockStore.refreshLocks();
71*51ba086bSDamjan Jovanovic nCount = nNth;
72*51ba086bSDamjan Jovanovic }
73*51ba086bSDamjan Jovanovic
74*51ba086bSDamjan Jovanovic TimeValue aTV;
75*51ba086bSDamjan Jovanovic aTV.Seconds = 0;
76*51ba086bSDamjan Jovanovic aTV.Nanosec = 1000000000 / nNth;
77*51ba086bSDamjan Jovanovic wait( aTV );
78*51ba086bSDamjan Jovanovic }
79*51ba086bSDamjan Jovanovic
80*51ba086bSDamjan Jovanovic OSL_TRACE( "TickerThread: stop." );
81*51ba086bSDamjan Jovanovic }
82*51ba086bSDamjan Jovanovic
83*51ba086bSDamjan Jovanovic // -------------------------------------------------------------------
CurlLockStore()84*51ba086bSDamjan Jovanovic CurlLockStore::CurlLockStore()
85*51ba086bSDamjan Jovanovic : m_pTickerThread( 0 )
86*51ba086bSDamjan Jovanovic {
87*51ba086bSDamjan Jovanovic }
88*51ba086bSDamjan Jovanovic
89*51ba086bSDamjan Jovanovic // -------------------------------------------------------------------
~CurlLockStore()90*51ba086bSDamjan Jovanovic CurlLockStore::~CurlLockStore()
91*51ba086bSDamjan Jovanovic {
92*51ba086bSDamjan Jovanovic stopTicker();
93*51ba086bSDamjan Jovanovic
94*51ba086bSDamjan Jovanovic // release active locks, if any.
95*51ba086bSDamjan Jovanovic OSL_ENSURE( m_aLockInfoMap.size() == 0,
96*51ba086bSDamjan Jovanovic "CurlLockStore::~CurlLockStore - Releasing active locks!" );
97*51ba086bSDamjan Jovanovic
98*51ba086bSDamjan Jovanovic LockInfoMap::const_iterator it( m_aLockInfoMap.begin() );
99*51ba086bSDamjan Jovanovic const LockInfoMap::const_iterator end( m_aLockInfoMap.end() );
100*51ba086bSDamjan Jovanovic while ( it != end )
101*51ba086bSDamjan Jovanovic {
102*51ba086bSDamjan Jovanovic CurlLock * pLock = (*it).first;
103*51ba086bSDamjan Jovanovic try
104*51ba086bSDamjan Jovanovic {
105*51ba086bSDamjan Jovanovic (*it).second.xSession->UNLOCK( pLock );
106*51ba086bSDamjan Jovanovic (*it).second.xSession->release();
107*51ba086bSDamjan Jovanovic }
108*51ba086bSDamjan Jovanovic catch (DAVException & )
109*51ba086bSDamjan Jovanovic {}
110*51ba086bSDamjan Jovanovic ++it;
111*51ba086bSDamjan Jovanovic }
112*51ba086bSDamjan Jovanovic }
113*51ba086bSDamjan Jovanovic
114*51ba086bSDamjan Jovanovic // -------------------------------------------------------------------
startTicker()115*51ba086bSDamjan Jovanovic void CurlLockStore::startTicker()
116*51ba086bSDamjan Jovanovic {
117*51ba086bSDamjan Jovanovic osl::MutexGuard aGuard( m_aMutex );
118*51ba086bSDamjan Jovanovic
119*51ba086bSDamjan Jovanovic if ( !m_pTickerThread )
120*51ba086bSDamjan Jovanovic {
121*51ba086bSDamjan Jovanovic m_pTickerThread = new TickerThread( *this );
122*51ba086bSDamjan Jovanovic m_pTickerThread->create();
123*51ba086bSDamjan Jovanovic }
124*51ba086bSDamjan Jovanovic }
125*51ba086bSDamjan Jovanovic
126*51ba086bSDamjan Jovanovic // -------------------------------------------------------------------
stopTicker()127*51ba086bSDamjan Jovanovic void CurlLockStore::stopTicker()
128*51ba086bSDamjan Jovanovic {
129*51ba086bSDamjan Jovanovic osl::MutexGuard aGuard( m_aMutex );
130*51ba086bSDamjan Jovanovic
131*51ba086bSDamjan Jovanovic if ( m_pTickerThread )
132*51ba086bSDamjan Jovanovic {
133*51ba086bSDamjan Jovanovic m_pTickerThread->finish();
134*51ba086bSDamjan Jovanovic m_pTickerThread->join();
135*51ba086bSDamjan Jovanovic delete m_pTickerThread;
136*51ba086bSDamjan Jovanovic m_pTickerThread = 0;
137*51ba086bSDamjan Jovanovic }
138*51ba086bSDamjan Jovanovic }
139*51ba086bSDamjan Jovanovic
140*51ba086bSDamjan Jovanovic #if 0 //not currently used
141*51ba086bSDamjan Jovanovic // -------------------------------------------------------------------
142*51ba086bSDamjan Jovanovic void CurlLockStore::registerSession( CurlSession /* aSession */ )
143*51ba086bSDamjan Jovanovic {
144*51ba086bSDamjan Jovanovic osl::MutexGuard aGuard( m_aMutex );
145*51ba086bSDamjan Jovanovic
146*51ba086bSDamjan Jovanovic }
147*51ba086bSDamjan Jovanovic #endif
148*51ba086bSDamjan Jovanovic
149*51ba086bSDamjan Jovanovic // -------------------------------------------------------------------
findByUri(rtl::OUString const & rUri)150*51ba086bSDamjan Jovanovic CurlLock * CurlLockStore::findByUri( rtl::OUString const & rUri)
151*51ba086bSDamjan Jovanovic {
152*51ba086bSDamjan Jovanovic osl::MutexGuard aGuard( m_aMutex );
153*51ba086bSDamjan Jovanovic
154*51ba086bSDamjan Jovanovic LockInfoMap::const_iterator it( m_aLockInfoMap.begin() );
155*51ba086bSDamjan Jovanovic const LockInfoMap::const_iterator end( m_aLockInfoMap.end() );
156*51ba086bSDamjan Jovanovic
157*51ba086bSDamjan Jovanovic while ( it != end )
158*51ba086bSDamjan Jovanovic {
159*51ba086bSDamjan Jovanovic CurlLock * pLock = (*it).first;
160*51ba086bSDamjan Jovanovic if( pLock->getResourceUri().equals( rUri ) )
161*51ba086bSDamjan Jovanovic {
162*51ba086bSDamjan Jovanovic return pLock;
163*51ba086bSDamjan Jovanovic }
164*51ba086bSDamjan Jovanovic ++it;
165*51ba086bSDamjan Jovanovic }
166*51ba086bSDamjan Jovanovic
167*51ba086bSDamjan Jovanovic return static_cast<CurlLock*>(0);
168*51ba086bSDamjan Jovanovic }
169*51ba086bSDamjan Jovanovic
170*51ba086bSDamjan Jovanovic // -------------------------------------------------------------------
addLock(CurlLock * pLock,rtl::Reference<CurlSession> const & xSession,sal_Int32 nLastChanceToSendRefreshRequest)171*51ba086bSDamjan Jovanovic void CurlLockStore::addLock( CurlLock * pLock,
172*51ba086bSDamjan Jovanovic rtl::Reference< CurlSession > const & xSession,
173*51ba086bSDamjan Jovanovic sal_Int32 nLastChanceToSendRefreshRequest )
174*51ba086bSDamjan Jovanovic {
175*51ba086bSDamjan Jovanovic osl::MutexGuard aGuard( m_aMutex );
176*51ba086bSDamjan Jovanovic
177*51ba086bSDamjan Jovanovic m_aLockInfoMap[ pLock ]
178*51ba086bSDamjan Jovanovic = LockInfo( xSession, nLastChanceToSendRefreshRequest );
179*51ba086bSDamjan Jovanovic //acquire this session, needed to manage the lock refresh
180*51ba086bSDamjan Jovanovic xSession->acquire();
181*51ba086bSDamjan Jovanovic
182*51ba086bSDamjan Jovanovic #if OSL_DEBUG_LEVEL > 0
183*51ba086bSDamjan Jovanovic rtl::OUString aOwner;
184*51ba086bSDamjan Jovanovic pLock->getLock().Owner >>= aOwner;
185*51ba086bSDamjan Jovanovic rtl::OUString aToken;
186*51ba086bSDamjan Jovanovic aToken = pLock->getLock().LockTokens[0];
187*51ba086bSDamjan Jovanovic OSL_TRACE("CurlLockStore::addLock: new lock added aOwner '%s', token '%s'",
188*51ba086bSDamjan Jovanovic rtl::OUStringToOString(aOwner, RTL_TEXTENCODING_UTF8).getStr(),
189*51ba086bSDamjan Jovanovic rtl::OUStringToOString(aToken, RTL_TEXTENCODING_UTF8).getStr() );
190*51ba086bSDamjan Jovanovic #endif
191*51ba086bSDamjan Jovanovic startTicker();
192*51ba086bSDamjan Jovanovic }
193*51ba086bSDamjan Jovanovic
194*51ba086bSDamjan Jovanovic #if 0 //not currently used
195*51ba086bSDamjan Jovanovic // -------------------------------------------------------------------
196*51ba086bSDamjan Jovanovic void CurlLockStore::updateLock( CurlLock * pLock,
197*51ba086bSDamjan Jovanovic sal_Int32 nLastChanceToSendRefreshRequest )
198*51ba086bSDamjan Jovanovic {
199*51ba086bSDamjan Jovanovic osl::MutexGuard aGuard( m_aMutex );
200*51ba086bSDamjan Jovanovic
201*51ba086bSDamjan Jovanovic LockInfoMap::iterator it( m_aLockInfoMap.find( pLock ) );
202*51ba086bSDamjan Jovanovic OSL_ENSURE( it != m_aLockInfoMap.end(),
203*51ba086bSDamjan Jovanovic "CurlLockStore::updateLock: lock not found!" );
204*51ba086bSDamjan Jovanovic
205*51ba086bSDamjan Jovanovic if ( it != m_aLockInfoMap.end() )
206*51ba086bSDamjan Jovanovic {
207*51ba086bSDamjan Jovanovic (*it).second.nLastChanceToSendRefreshRequest
208*51ba086bSDamjan Jovanovic = nLastChanceToSendRefreshRequest;
209*51ba086bSDamjan Jovanovic }
210*51ba086bSDamjan Jovanovic }
211*51ba086bSDamjan Jovanovic #endif
212*51ba086bSDamjan Jovanovic
213*51ba086bSDamjan Jovanovic // -------------------------------------------------------------------
removeLock(CurlLock * pLock)214*51ba086bSDamjan Jovanovic void CurlLockStore::removeLock( CurlLock * pLock )
215*51ba086bSDamjan Jovanovic {
216*51ba086bSDamjan Jovanovic osl::MutexGuard aGuard( m_aMutex );
217*51ba086bSDamjan Jovanovic
218*51ba086bSDamjan Jovanovic LockInfoMap::iterator it( m_aLockInfoMap.find( pLock ) );
219*51ba086bSDamjan Jovanovic if(it != m_aLockInfoMap.end())
220*51ba086bSDamjan Jovanovic {
221*51ba086bSDamjan Jovanovic LockInfo & rInfo = (*it).second;
222*51ba086bSDamjan Jovanovic rInfo.xSession->release();
223*51ba086bSDamjan Jovanovic m_aLockInfoMap.erase( pLock );
224*51ba086bSDamjan Jovanovic //the caller should deallocate CurlLock class after the call!
225*51ba086bSDamjan Jovanovic if ( m_aLockInfoMap.size() == 0 )
226*51ba086bSDamjan Jovanovic stopTicker();
227*51ba086bSDamjan Jovanovic }
228*51ba086bSDamjan Jovanovic }
229*51ba086bSDamjan Jovanovic
230*51ba086bSDamjan Jovanovic // -------------------------------------------------------------------
refreshLocks()231*51ba086bSDamjan Jovanovic void CurlLockStore::refreshLocks()
232*51ba086bSDamjan Jovanovic {
233*51ba086bSDamjan Jovanovic osl::MutexGuard aGuard( m_aMutex );
234*51ba086bSDamjan Jovanovic
235*51ba086bSDamjan Jovanovic LockInfoMap::iterator it( m_aLockInfoMap.begin() );
236*51ba086bSDamjan Jovanovic const LockInfoMap::const_iterator end( m_aLockInfoMap.end() );
237*51ba086bSDamjan Jovanovic while ( it != end )
238*51ba086bSDamjan Jovanovic {
239*51ba086bSDamjan Jovanovic LockInfo & rInfo = (*it).second;
240*51ba086bSDamjan Jovanovic if ( rInfo.nLastChanceToSendRefreshRequest != -1 )
241*51ba086bSDamjan Jovanovic {
242*51ba086bSDamjan Jovanovic // 30 seconds or less remaining until lock expires?
243*51ba086bSDamjan Jovanovic TimeValue t1;
244*51ba086bSDamjan Jovanovic osl_getSystemTime( &t1 );
245*51ba086bSDamjan Jovanovic if ( rInfo.nLastChanceToSendRefreshRequest - 30
246*51ba086bSDamjan Jovanovic <= sal_Int32( t1.Seconds ) )
247*51ba086bSDamjan Jovanovic {
248*51ba086bSDamjan Jovanovic // refresh the lock.
249*51ba086bSDamjan Jovanovic #if OSL_DEBUG_LEVEL > 0
250*51ba086bSDamjan Jovanovic ucb::Lock aLock = (*it).first->getLock();
251*51ba086bSDamjan Jovanovic rtl::OUString aOwner;
252*51ba086bSDamjan Jovanovic aLock.Owner >>= aOwner;
253*51ba086bSDamjan Jovanovic rtl::OUString aToken;
254*51ba086bSDamjan Jovanovic aToken = aLock.LockTokens[0];
255*51ba086bSDamjan Jovanovic OSL_TRACE( "CurlLockStore::refreshLocks: refresh started for lock: aOwner '%s', token '%s'",
256*51ba086bSDamjan Jovanovic rtl::OUStringToOString(aOwner, RTL_TEXTENCODING_UTF8).getStr(),
257*51ba086bSDamjan Jovanovic rtl::OUStringToOString(aToken, RTL_TEXTENCODING_UTF8).getStr() );
258*51ba086bSDamjan Jovanovic #endif
259*51ba086bSDamjan Jovanovic sal_Int32 nlastChanceToSendRefreshRequest = -1;
260*51ba086bSDamjan Jovanovic try
261*51ba086bSDamjan Jovanovic {
262*51ba086bSDamjan Jovanovic rInfo.xSession->LOCK( (*it).first,
263*51ba086bSDamjan Jovanovic /* out param */ nlastChanceToSendRefreshRequest );
264*51ba086bSDamjan Jovanovic rInfo.nLastChanceToSendRefreshRequest
265*51ba086bSDamjan Jovanovic = nlastChanceToSendRefreshRequest;
266*51ba086bSDamjan Jovanovic #if OSL_DEBUG_LEVEL > 0
267*51ba086bSDamjan Jovanovic OSL_TRACE( "Lock '%s' successfully refreshed." ,
268*51ba086bSDamjan Jovanovic rtl::OUStringToOString(aToken, RTL_TEXTENCODING_UTF8).getStr() );
269*51ba086bSDamjan Jovanovic #endif
270*51ba086bSDamjan Jovanovic }
271*51ba086bSDamjan Jovanovic catch ( DAVException & e )
272*51ba086bSDamjan Jovanovic {
273*51ba086bSDamjan Jovanovic // refresh failed. stop auto-refresh.
274*51ba086bSDamjan Jovanovic // TODO i126305 discuss:
275*51ba086bSDamjan Jovanovic // probably not a good idea to stop the refresh?
276*51ba086bSDamjan Jovanovic // may be just ignore and go on, it's possible the net is temporary down?
277*51ba086bSDamjan Jovanovic rInfo.nLastChanceToSendRefreshRequest = -1;
278*51ba086bSDamjan Jovanovic #if OSL_DEBUG_LEVEL > 0
279*51ba086bSDamjan Jovanovic OSL_TRACE( "CurlLockStore::refreshLocks: Lock '%s' not refreshed! (error: DAVException.mStatusCode %d)",
280*51ba086bSDamjan Jovanovic rtl::OUStringToOString(aToken, RTL_TEXTENCODING_UTF8).getStr(), e.getStatus() );
281*51ba086bSDamjan Jovanovic #endif
282*51ba086bSDamjan Jovanovic }
283*51ba086bSDamjan Jovanovic }
284*51ba086bSDamjan Jovanovic }
285*51ba086bSDamjan Jovanovic ++it;
286*51ba086bSDamjan Jovanovic }
287*51ba086bSDamjan Jovanovic }
288