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