Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <threadhelp/lockhelper.hxx>
21 : #include <general.h>
22 : #include <macros/debug.hxx>
23 :
24 : #include <macros/generic.hxx>
25 : #include "vcl/solarmutex.hxx"
26 :
27 : #include <osl/process.h>
28 :
29 : namespace framework{
30 :
31 : /*-************************************************************************************************************//**
32 : @short use ctor to initialize instance
33 :
34 : @seealso class ReadGuard
35 : @seealso class WriteGuard
36 :
37 : @param "rSolarMutex", for some components we must be "vcl-free"! So we can't work with our solar mutex
38 : directly. User must set his reference at this instance - so we can work with it!
39 : @return -
40 :
41 : @onerror -
42 : *//*-*************************************************************************************************************/
43 156432 : LockHelper::LockHelper( comphelper::SolarMutex* pSolarMutex )
44 : : m_pSolarMutex ( NULL )
45 : , m_pShareableOslMutex( NULL )
46 156432 : , m_bDummySolarMutex ( sal_False )
47 : {
48 156432 : if( pSolarMutex == NULL )
49 : {
50 87500 : m_pSolarMutex = new ::vcl::SolarMutexObject;
51 87500 : m_bDummySolarMutex = sal_True;
52 : }
53 : else
54 : {
55 68932 : m_pSolarMutex = pSolarMutex;
56 : }
57 156432 : }
58 :
59 : /*-************************************************************************************************************//**
60 : @short default dtor to release safed pointer
61 : @descr We have created dynamical mutex- or lock-member ... or we hold a pointer to external objects.
62 : We must release it!
63 :
64 : @seealso ctor()
65 :
66 : @param -
67 : @return -
68 :
69 : @onerror -
70 : *//*-*************************************************************************************************************/
71 309556 : LockHelper::~LockHelper()
72 : {
73 154778 : if( m_pShareableOslMutex != NULL )
74 : {
75 38026 : delete m_pShareableOslMutex;
76 38026 : m_pShareableOslMutex = NULL;
77 : }
78 154778 : if( m_pSolarMutex != NULL )
79 : {
80 154778 : if (m_bDummySolarMutex)
81 : {
82 87311 : delete static_cast<vcl::SolarMutexObject*>(m_pSolarMutex);
83 87311 : m_bDummySolarMutex = sal_False;
84 : }
85 154778 : m_pSolarMutex = NULL;
86 : }
87 154778 : }
88 :
89 : /*-************************************************************************************************************//**
90 : @interface IMutex
91 : @short set an exclusiv lock
92 : @descr We must match this lock call with current set lock type and used lock member.
93 : If a mutex should be used - it will be easy ... but if a rw-lock should be used
94 : we must simulate it as a write access!
95 :
96 : @attention If a shareable osl mutex exist, he must be used as twice!
97 : It's neccessary for some cppu-helper classes ...
98 :
99 : @seealso method acquireWriteAccess()
100 :
101 : @param -
102 : @return -
103 :
104 : @onerror -
105 : *//*-*************************************************************************************************************/
106 1417827 : void LockHelper::acquire()
107 : {
108 1417827 : m_pSolarMutex->acquire();
109 1417827 : }
110 :
111 : /*-************************************************************************************************************//**
112 : @interface IMutex
113 : @short release exclusiv lock
114 : @descr We must match this unlock call with current set lock type and used lock member.
115 : If a mutex should be used - it will be easy ... but if a rw-lock should be used
116 : we must simulate it as a write access!
117 :
118 : @attention If a shareable osl mutex exist, he must be used as twice!
119 : It's neccessary for some cppu-helper classes ...
120 :
121 : @seealso method releaseWriteAccess()
122 :
123 : @param -
124 : @return -
125 :
126 : @onerror -
127 : *//*-*************************************************************************************************************/
128 1417827 : void LockHelper::release()
129 : {
130 1417827 : m_pSolarMutex->release();
131 1417827 : }
132 :
133 : /*-************************************************************************************************************//**
134 : @interface IRWLock
135 : @short set lock for reading
136 : @descr A guard should call this method to acquire read access on your member.
137 : Writing isn't allowed then - but nobody could check it for you!
138 :
139 : @attention If a shareable osl mutex exist, he must be used as twice!
140 : It's neccessary for some cppu-helper classes ...
141 :
142 : @seealso method releaseReadAccess()
143 :
144 : @param -
145 : @return -
146 :
147 : @onerror -
148 : *//*-*************************************************************************************************************/
149 2161270 : void LockHelper::acquireReadAccess()
150 : {
151 2161270 : m_pSolarMutex->acquire();
152 2161270 : }
153 :
154 : /*-************************************************************************************************************//**
155 : @interface IRWLock
156 : @short reset lock for reading
157 : @descr A guard should call this method to release read access on your member.
158 :
159 : @attention If a shareable osl mutex exist, he must be used as twice!
160 : It's neccessary for some cppu-helper classes ...
161 :
162 : @seealso method acquireReadAccess()
163 :
164 : @param -
165 : @return -
166 :
167 : @onerror -
168 : *//*-*************************************************************************************************************/
169 2162369 : void LockHelper::releaseReadAccess()
170 : {
171 2162369 : m_pSolarMutex->release();
172 2162369 : }
173 :
174 : /*-************************************************************************************************************//**
175 : @interface IRWLock
176 : @short set lock for writing
177 : @descr A guard should call this method to acquire write access on your member.
178 : Reading is allowed too - of course.
179 : After successfully calling of this method you are the only writer.
180 :
181 : @attention If a shareable osl mutex exist, he must be used as twice!
182 : It's neccessary for some cppu-helper classes ...
183 :
184 : @seealso method releaseWriteAccess()
185 :
186 : @param -
187 : @return -
188 :
189 : @onerror -
190 : *//*-*************************************************************************************************************/
191 600780 : void LockHelper::acquireWriteAccess()
192 : {
193 600780 : m_pSolarMutex->acquire();
194 600780 : }
195 :
196 : /*-************************************************************************************************************//**
197 : @interface IRWLock
198 : @short reset lock for writing
199 : @descr A guard should call this method to release write access on your member.
200 :
201 : @attention If a shareable osl mutex exist, he must be used as twice!
202 : It's neccessary for some cppu-helper classes ...
203 :
204 : @seealso method acquireWriteAccess()
205 :
206 : @param -
207 : @return -
208 :
209 : @onerror -
210 : *//*-*************************************************************************************************************/
211 599681 : void LockHelper::releaseWriteAccess()
212 : {
213 599681 : m_pSolarMutex->release();
214 599681 : }
215 :
216 : /*-************************************************************************************************************//**
217 : @interface IRWLock
218 : @short downgrade a write access to a read access
219 : @descr A guard should call this method to change a write to a read access.
220 : New readers can work too - new writer are blocked!
221 :
222 : @attention Ignore shareable mutex(!) - because this call never should release a lock completely!
223 : We change a write access to a read access only.
224 :
225 : @attention a) Don't call this method if you are not a writer!
226 : Results are not defined then ...
227 : An upgrade can't be implemented realy ... because acquiring new access
228 : will be the same - there no differences!
229 : b) Without function ...
230 : because, a mutex don't support it realy.
231 :
232 : @seealso -
233 :
234 : @param -
235 : @return -
236 :
237 : @onerror -
238 : *//*-*************************************************************************************************************/
239 1099 : void LockHelper::downgradeWriteAccess()
240 : {
241 : // Not supported for mutex!
242 1099 : }
243 :
244 : /*-************************************************************************************************************//**
245 : @short return a reference to a static lock helper
246 : @descr Sometimes we need the global mutex or rw-lock! (e.g. in our own static methods)
247 : But it's not a good idea to use these global one very often ...
248 : Thats why we use this little helper method.
249 : We create our own "class global static" lock.
250 : It will be created at first call only!
251 : All other requests use these created one then directly.
252 :
253 : @seealso -
254 :
255 : @param -
256 : @return A reference to a static mutex/lock member.
257 :
258 : @onerror No error should occure.
259 : *//*-*************************************************************************************************************/
260 13990 : LockHelper& LockHelper::getGlobalLock()
261 : {
262 : // Initialize static "member" only for one time!
263 : // Algorithm:
264 : // a) Start with an invalid lock (NULL pointer)
265 : // b) If these method first called (lock not already exist!) ...
266 : // c) ... we must create a new one. Protect follow code with the global mutex -
267 : // (It must be - we create a static variable!)
268 : // d) Check pointer again - because ... another instance of our class could be faster then these one!
269 : // e) Create the new lock and set it for return on static variable.
270 : // f) Return new created or already existing lock object.
271 : static LockHelper* pLock = NULL;
272 13990 : if( pLock == NULL )
273 : {
274 134 : ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
275 134 : if( pLock == NULL )
276 : {
277 134 : static LockHelper aLock;
278 134 : pLock = &aLock;
279 134 : }
280 : }
281 13990 : return *pLock;
282 : }
283 :
284 : /*-************************************************************************************************************//**
285 : @short return a reference to shared mutex member
286 : @descr Sometimes we need a osl-mutex for sharing with our uno helper ...
287 : What can we do?
288 : We must use a different mutex member :-(
289 : I HOPE IT WORKS!
290 :
291 : @seealso -
292 :
293 : @param -
294 : @return A reference to a shared mutex.
295 :
296 : @onerror No error should occure.
297 : *//*-*************************************************************************************************************/
298 47205 : ::osl::Mutex& LockHelper::getShareableOslMutex()
299 : {
300 47205 : if( m_pShareableOslMutex == NULL )
301 : {
302 38110 : ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
303 38110 : if( m_pShareableOslMutex == NULL )
304 : {
305 38110 : m_pShareableOslMutex = new ::osl::Mutex;
306 38110 : }
307 : }
308 47205 : return *m_pShareableOslMutex;
309 : }
310 :
311 : } // namespace framework
312 :
313 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|