1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
31 #include "rtl/ustring.hxx"
33 #include "osl/thread.hxx"
34 #include "salhelper/thread.hxx"
35 #include "NeonSession.hxx"
36 #include "NeonLockStore.hxx"
38 using namespace webdav_ucp
;
40 namespace webdav_ucp
{
42 class TickerThread
: public salhelper::Thread
45 NeonLockStore
& m_rLockStore
;
49 TickerThread( NeonLockStore
& rLockStore
)
50 : Thread( "NeonTickerThread" ), m_bFinish( false ),
51 m_rLockStore( rLockStore
) {}
53 void finish() { m_bFinish
= true; }
57 virtual void execute();
60 } // namespace webdav_ucp
62 void TickerThread::execute()
64 OSL_TRACE( "TickerThread: start." );
66 // we have to go through the loop more often to be able to finish ~quickly
74 m_rLockStore
.refreshLocks();
80 aTV
.Nanosec
= 1000000000 / nNth
;
81 salhelper::Thread::wait( aTV
);
84 OSL_TRACE( "TickerThread: stop." );
87 NeonLockStore::NeonLockStore()
88 : m_pNeonLockStore( ne_lockstore_create() )
90 OSL_ENSURE( m_pNeonLockStore
, "Unable to create neon lock store!" );
93 NeonLockStore::~NeonLockStore()
95 osl::ResettableMutexGuard
aGuard(m_aMutex
);
97 aGuard
.reset(); // actually no threads should even try to access members now
99 // release active locks, if any.
100 OSL_ENSURE( m_aLockInfoMap
.empty(),
101 "NeonLockStore::~NeonLockStore - Releasing active locks!" );
103 LockInfoMap::const_iterator
it( m_aLockInfoMap
.begin() );
104 const LockInfoMap::const_iterator
end( m_aLockInfoMap
.end() );
107 NeonLock
* pLock
= (*it
).first
;
108 (*it
).second
.xSession
->UNLOCK( pLock
);
110 ne_lockstore_remove( m_pNeonLockStore
, pLock
);
111 ne_lock_destroy( pLock
);
116 ne_lockstore_destroy( m_pNeonLockStore
);
119 void NeonLockStore::startTicker()
121 osl::MutexGuard
aGuard( m_aMutex
);
123 if ( !m_pTickerThread
.is() )
125 m_pTickerThread
= new TickerThread( *this );
126 m_pTickerThread
->launch();
130 void NeonLockStore::stopTicker(osl::ClearableMutexGuard
& rGuard
)
132 rtl::Reference
<TickerThread
> pTickerThread
;
134 if (m_pTickerThread
.is())
136 m_pTickerThread
->finish(); // needs mutex
137 // the TickerThread may run refreshLocks() at most once after this
138 pTickerThread
= m_pTickerThread
;
139 m_pTickerThread
.clear();
144 if (pTickerThread
.is())
145 pTickerThread
->join(); // without m_aMutex locked (to prevent deadlock)
148 void NeonLockStore::registerSession( HttpSession
* pHttpSession
)
150 osl::MutexGuard
aGuard( m_aMutex
);
152 ne_lockstore_register( m_pNeonLockStore
, pHttpSession
);
155 NeonLock
* NeonLockStore::findByUri( OUString
const & rUri
)
157 osl::MutexGuard
aGuard( m_aMutex
);
160 ne_uri_parse( OUStringToOString(
161 rUri
, RTL_TEXTENCODING_UTF8
).getStr(), &aUri
);
162 return ne_lockstore_findbyuri( m_pNeonLockStore
, &aUri
);
165 void NeonLockStore::addLock( NeonLock
* pLock
,
166 rtl::Reference
< NeonSession
> const & xSession
,
167 sal_Int32 nLastChanceToSendRefreshRequest
)
169 osl::MutexGuard
aGuard( m_aMutex
);
171 ne_lockstore_add( m_pNeonLockStore
, pLock
);
172 m_aLockInfoMap
[ pLock
]
173 = LockInfo( xSession
, nLastChanceToSendRefreshRequest
);
178 void NeonLockStore::updateLock( NeonLock
* pLock
,
179 sal_Int32 nLastChanceToSendRefreshRequest
)
181 osl::MutexGuard
aGuard( m_aMutex
);
183 LockInfoMap::iterator
it( m_aLockInfoMap
.find( pLock
) );
184 OSL_ENSURE( it
!= m_aLockInfoMap
.end(),
185 "NeonLockStore::updateLock: lock not found!" );
187 if ( it
!= m_aLockInfoMap
.end() )
189 (*it
).second
.nLastChanceToSendRefreshRequest
190 = nLastChanceToSendRefreshRequest
;
194 void NeonLockStore::removeLock( NeonLock
* pLock
)
196 osl::ClearableMutexGuard
aGuard( m_aMutex
);
198 m_aLockInfoMap
.erase( pLock
);
199 ne_lockstore_remove( m_pNeonLockStore
, pLock
);
201 if ( m_aLockInfoMap
.empty() )
205 void NeonLockStore::refreshLocks()
207 osl::MutexGuard
aGuard( m_aMutex
);
209 LockInfoMap::iterator
it( m_aLockInfoMap
.begin() );
210 const LockInfoMap::const_iterator
end( m_aLockInfoMap
.end() );
213 LockInfo
& rInfo
= (*it
).second
;
214 if ( rInfo
.nLastChanceToSendRefreshRequest
!= -1 )
216 // 30 seconds or less remaining until lock expires?
218 osl_getSystemTime( &t1
);
219 if ( rInfo
.nLastChanceToSendRefreshRequest
- 30
220 <= sal_Int32( t1
.Seconds
) )
223 sal_Int32 nlastChanceToSendRefreshRequest
= -1;
224 if ( rInfo
.xSession
->LOCK(
226 /* out param */ nlastChanceToSendRefreshRequest
) )
228 rInfo
.nLastChanceToSendRefreshRequest
229 = nlastChanceToSendRefreshRequest
;
233 // refresh failed. stop auto-refresh.
234 rInfo
.nLastChanceToSendRefreshRequest
= -1;
242 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */