1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_framework.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
32*cdf0e10cSrcweir //	my own includes
33*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
34*cdf0e10cSrcweir #include <threadhelp/lockhelper.hxx>
35*cdf0e10cSrcweir #include <general.h>
36*cdf0e10cSrcweir #include <macros/debug.hxx>
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir #include <macros/generic.hxx>
39*cdf0e10cSrcweir 
40*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
41*cdf0e10cSrcweir //	interface includes
42*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
45*cdf0e10cSrcweir //	other includes
46*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
47*cdf0e10cSrcweir #include <vos/process.hxx>
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
50*cdf0e10cSrcweir //	namespace
51*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir namespace framework{
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
56*cdf0e10cSrcweir //	const
57*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
60*cdf0e10cSrcweir //	declarations
61*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir /*-************************************************************************************************************//**
64*cdf0e10cSrcweir     @short      use ctor to initialize instance
65*cdf0e10cSrcweir     @descr      We must initialize our member "m_eLockType". This value specify handling of locking.
66*cdf0e10cSrcweir                 User use this helper as parameter for a guard creation.
67*cdf0e10cSrcweir                 These guard use "m_eLockType" to set lock in the right way by using right mutex or rw-lock.
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir     @seealso    enum ELockType
70*cdf0e10cSrcweir     @seealso    class ReadGuard
71*cdf0e10cSrcweir     @seealso    class WriteGuard
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir     @param      "rSolarMutex", for some components we must be "vcl-free"! So we can't work with our solar mutex
74*cdf0e10cSrcweir                                 directly. User must set his reference at this instance - so we can work with it!
75*cdf0e10cSrcweir     @return     -
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir     @onerror    -
78*cdf0e10cSrcweir *//*-*************************************************************************************************************/
79*cdf0e10cSrcweir LockHelper::LockHelper( ::vos::IMutex* pSolarMutex )
80*cdf0e10cSrcweir     :   m_pFairRWLock       ( NULL )
81*cdf0e10cSrcweir     ,   m_pOwnMutex         ( NULL )
82*cdf0e10cSrcweir     ,   m_pSolarMutex       ( NULL )
83*cdf0e10cSrcweir     ,   m_pShareableOslMutex( NULL )
84*cdf0e10cSrcweir     ,   m_bDummySolarMutex  ( sal_False )
85*cdf0e10cSrcweir {
86*cdf0e10cSrcweir     m_eLockType = implts_getLockType();
87*cdf0e10cSrcweir     switch( m_eLockType )
88*cdf0e10cSrcweir     {
89*cdf0e10cSrcweir         case E_NOTHING      :   break; // There is nothing to do ...
90*cdf0e10cSrcweir         case E_OWNMUTEX     :   {
91*cdf0e10cSrcweir                                     m_pOwnMutex = new ::osl::Mutex;
92*cdf0e10cSrcweir                                 }
93*cdf0e10cSrcweir                                 break;
94*cdf0e10cSrcweir         case E_SOLARMUTEX   :   {
95*cdf0e10cSrcweir                                     if( pSolarMutex == NULL )
96*cdf0e10cSrcweir                                     {
97*cdf0e10cSrcweir                                         m_pSolarMutex      = new ::vos::OMutex;
98*cdf0e10cSrcweir                                         m_bDummySolarMutex = sal_True;
99*cdf0e10cSrcweir                                     }
100*cdf0e10cSrcweir                                     else
101*cdf0e10cSrcweir                                     {
102*cdf0e10cSrcweir                                         m_pSolarMutex = pSolarMutex;
103*cdf0e10cSrcweir                                     }
104*cdf0e10cSrcweir                                 }
105*cdf0e10cSrcweir                                 break;
106*cdf0e10cSrcweir         case E_FAIRRWLOCK   :   {
107*cdf0e10cSrcweir                                     m_pFairRWLock = new FairRWLock;
108*cdf0e10cSrcweir                                 }
109*cdf0e10cSrcweir                                 break;
110*cdf0e10cSrcweir         #ifdef ENABLE_ASSERTIONS
111*cdf0e10cSrcweir         default             :   LOG_ASSERT2( m_eLockType!=E_NOTHING, "LockHelper::ctor()", "Invalid lock type found .. so code will not be threadsafe!" )
112*cdf0e10cSrcweir         #endif
113*cdf0e10cSrcweir     }
114*cdf0e10cSrcweir }
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir /*-************************************************************************************************************//**
117*cdf0e10cSrcweir     @short      default dtor to release safed pointer
118*cdf0e10cSrcweir     @descr      We have created dynamical mutex- or lock-member ... or we hold a pointer to external objects.
119*cdf0e10cSrcweir                 We must release it!
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir     @seealso    ctor()
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir     @param      -
124*cdf0e10cSrcweir     @return     -
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir     @onerror    -
127*cdf0e10cSrcweir *//*-*************************************************************************************************************/
128*cdf0e10cSrcweir LockHelper::~LockHelper()
129*cdf0e10cSrcweir {
130*cdf0e10cSrcweir     if( m_pShareableOslMutex != NULL )
131*cdf0e10cSrcweir     {
132*cdf0e10cSrcweir         // Sometimes we hold two pointer to same object!
133*cdf0e10cSrcweir         // (e.g. if m_eLockType==E_OWNMUTEX!)
134*cdf0e10cSrcweir         // So we should forget it ... but don't delete it twice!
135*cdf0e10cSrcweir         if( m_pShareableOslMutex != m_pOwnMutex )
136*cdf0e10cSrcweir         {
137*cdf0e10cSrcweir             delete m_pShareableOslMutex;
138*cdf0e10cSrcweir         }
139*cdf0e10cSrcweir         m_pShareableOslMutex = NULL;
140*cdf0e10cSrcweir     }
141*cdf0e10cSrcweir     if( m_pOwnMutex != NULL )
142*cdf0e10cSrcweir     {
143*cdf0e10cSrcweir         delete m_pOwnMutex;
144*cdf0e10cSrcweir         m_pOwnMutex = NULL;
145*cdf0e10cSrcweir     }
146*cdf0e10cSrcweir     if( m_pSolarMutex != NULL )
147*cdf0e10cSrcweir     {
148*cdf0e10cSrcweir         if (m_bDummySolarMutex)
149*cdf0e10cSrcweir         {
150*cdf0e10cSrcweir             delete static_cast<vos::OMutex*>(m_pSolarMutex);
151*cdf0e10cSrcweir             m_bDummySolarMutex = sal_False;
152*cdf0e10cSrcweir         }
153*cdf0e10cSrcweir         m_pSolarMutex = NULL;
154*cdf0e10cSrcweir     }
155*cdf0e10cSrcweir     if( m_pFairRWLock != NULL )
156*cdf0e10cSrcweir     {
157*cdf0e10cSrcweir         delete m_pFairRWLock;
158*cdf0e10cSrcweir         m_pFairRWLock = NULL;
159*cdf0e10cSrcweir     }
160*cdf0e10cSrcweir }
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir /*-************************************************************************************************************//**
163*cdf0e10cSrcweir     @interface  IMutex
164*cdf0e10cSrcweir     @short      set an exclusiv lock
165*cdf0e10cSrcweir     @descr      We must match this lock call with current set lock type and used lock member.
166*cdf0e10cSrcweir                 If a mutex should be used - it will be easy ... but if a rw-lock should be used
167*cdf0e10cSrcweir                 we must simulate it as a write access!
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir     @attention  If a shareable osl mutex exist, he must be used as twice!
170*cdf0e10cSrcweir                 It's neccessary for some cppu-helper classes ...
171*cdf0e10cSrcweir 
172*cdf0e10cSrcweir     @seealso    method acquireWriteAccess()
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir     @param      -
175*cdf0e10cSrcweir     @return     -
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir     @onerror    -
178*cdf0e10cSrcweir *//*-*************************************************************************************************************/
179*cdf0e10cSrcweir void LockHelper::acquire()
180*cdf0e10cSrcweir {
181*cdf0e10cSrcweir     switch( m_eLockType )
182*cdf0e10cSrcweir     {
183*cdf0e10cSrcweir         case E_NOTHING      :   break; // There is nothing to do ...
184*cdf0e10cSrcweir         case E_OWNMUTEX     :   {
185*cdf0e10cSrcweir                                     m_pOwnMutex->acquire();
186*cdf0e10cSrcweir                                 }
187*cdf0e10cSrcweir                                 break;
188*cdf0e10cSrcweir         case E_SOLARMUTEX   :   {
189*cdf0e10cSrcweir                                     m_pSolarMutex->acquire();
190*cdf0e10cSrcweir                                 }
191*cdf0e10cSrcweir                                 break;
192*cdf0e10cSrcweir         case E_FAIRRWLOCK   :   {
193*cdf0e10cSrcweir                                     m_pFairRWLock->acquireWriteAccess();
194*cdf0e10cSrcweir                                 }
195*cdf0e10cSrcweir                                 break;
196*cdf0e10cSrcweir     }
197*cdf0e10cSrcweir }
198*cdf0e10cSrcweir 
199*cdf0e10cSrcweir /*-************************************************************************************************************//**
200*cdf0e10cSrcweir     @interface  IMutex
201*cdf0e10cSrcweir     @short      release exclusiv lock
202*cdf0e10cSrcweir     @descr      We must match this unlock call with current set lock type and used lock member.
203*cdf0e10cSrcweir                 If a mutex should be used - it will be easy ... but if a rw-lock should be used
204*cdf0e10cSrcweir                 we must simulate it as a write access!
205*cdf0e10cSrcweir 
206*cdf0e10cSrcweir     @attention  If a shareable osl mutex exist, he must be used as twice!
207*cdf0e10cSrcweir                 It's neccessary for some cppu-helper classes ...
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir     @seealso    method releaseWriteAccess()
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir     @param      -
212*cdf0e10cSrcweir     @return     -
213*cdf0e10cSrcweir 
214*cdf0e10cSrcweir     @onerror    -
215*cdf0e10cSrcweir *//*-*************************************************************************************************************/
216*cdf0e10cSrcweir void LockHelper::release()
217*cdf0e10cSrcweir {
218*cdf0e10cSrcweir     switch( m_eLockType )
219*cdf0e10cSrcweir     {
220*cdf0e10cSrcweir         case E_NOTHING      :   break; // There is nothing to do ...
221*cdf0e10cSrcweir         case E_OWNMUTEX     :   {
222*cdf0e10cSrcweir                                     m_pOwnMutex->release();
223*cdf0e10cSrcweir                                 }
224*cdf0e10cSrcweir                                 break;
225*cdf0e10cSrcweir         case E_SOLARMUTEX   :   {
226*cdf0e10cSrcweir                                     m_pSolarMutex->release();
227*cdf0e10cSrcweir                                 }
228*cdf0e10cSrcweir                                 break;
229*cdf0e10cSrcweir         case E_FAIRRWLOCK   :   {
230*cdf0e10cSrcweir                                     m_pFairRWLock->releaseWriteAccess();
231*cdf0e10cSrcweir                                 }
232*cdf0e10cSrcweir                                 break;
233*cdf0e10cSrcweir     }
234*cdf0e10cSrcweir }
235*cdf0e10cSrcweir 
236*cdf0e10cSrcweir /*-************************************************************************************************************//**
237*cdf0e10cSrcweir     @interface  IRWLock
238*cdf0e10cSrcweir     @short      set lock for reading
239*cdf0e10cSrcweir     @descr      A guard should call this method to acquire read access on your member.
240*cdf0e10cSrcweir                 Writing isn't allowed then - but nobody could check it for you!
241*cdf0e10cSrcweir                 We use m_eLockType to differ between all possible "lock-member"!!!
242*cdf0e10cSrcweir 
243*cdf0e10cSrcweir     @attention  If a shareable osl mutex exist, he must be used as twice!
244*cdf0e10cSrcweir                 It's neccessary for some cppu-helper classes ...
245*cdf0e10cSrcweir 
246*cdf0e10cSrcweir     @seealso    method releaseReadAccess()
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir     @param      -
249*cdf0e10cSrcweir     @return     -
250*cdf0e10cSrcweir 
251*cdf0e10cSrcweir     @onerror    -
252*cdf0e10cSrcweir *//*-*************************************************************************************************************/
253*cdf0e10cSrcweir void LockHelper::acquireReadAccess()
254*cdf0e10cSrcweir {
255*cdf0e10cSrcweir     switch( m_eLockType )
256*cdf0e10cSrcweir     {
257*cdf0e10cSrcweir         case E_NOTHING      :   break; // There is nothing to do ...
258*cdf0e10cSrcweir         case E_OWNMUTEX     :   {
259*cdf0e10cSrcweir                                     m_pOwnMutex->acquire();
260*cdf0e10cSrcweir                                 }
261*cdf0e10cSrcweir                                 break;
262*cdf0e10cSrcweir         case E_SOLARMUTEX   :   {
263*cdf0e10cSrcweir                                     m_pSolarMutex->acquire();
264*cdf0e10cSrcweir                                 }
265*cdf0e10cSrcweir                                 break;
266*cdf0e10cSrcweir         case E_FAIRRWLOCK   :   {
267*cdf0e10cSrcweir                                     m_pFairRWLock->acquireReadAccess();
268*cdf0e10cSrcweir                                 }
269*cdf0e10cSrcweir                                 break;
270*cdf0e10cSrcweir     }
271*cdf0e10cSrcweir }
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir /*-************************************************************************************************************//**
274*cdf0e10cSrcweir     @interface  IRWLock
275*cdf0e10cSrcweir     @short      reset lock for reading
276*cdf0e10cSrcweir     @descr      A guard should call this method to release read access on your member.
277*cdf0e10cSrcweir                 We use m_eLockType to differ between all possible "lock-member"!!!
278*cdf0e10cSrcweir 
279*cdf0e10cSrcweir     @attention  If a shareable osl mutex exist, he must be used as twice!
280*cdf0e10cSrcweir                 It's neccessary for some cppu-helper classes ...
281*cdf0e10cSrcweir 
282*cdf0e10cSrcweir     @seealso    method acquireReadAccess()
283*cdf0e10cSrcweir 
284*cdf0e10cSrcweir     @param      -
285*cdf0e10cSrcweir     @return     -
286*cdf0e10cSrcweir 
287*cdf0e10cSrcweir     @onerror    -
288*cdf0e10cSrcweir *//*-*************************************************************************************************************/
289*cdf0e10cSrcweir void LockHelper::releaseReadAccess()
290*cdf0e10cSrcweir {
291*cdf0e10cSrcweir     switch( m_eLockType )
292*cdf0e10cSrcweir     {
293*cdf0e10cSrcweir         case E_NOTHING      :   break; // There is nothing to do ...
294*cdf0e10cSrcweir         case E_OWNMUTEX     :   {
295*cdf0e10cSrcweir                                     m_pOwnMutex->release();
296*cdf0e10cSrcweir                                 }
297*cdf0e10cSrcweir                                 break;
298*cdf0e10cSrcweir         case E_SOLARMUTEX   :   {
299*cdf0e10cSrcweir                                     m_pSolarMutex->release();
300*cdf0e10cSrcweir                                 }
301*cdf0e10cSrcweir                                 break;
302*cdf0e10cSrcweir         case E_FAIRRWLOCK   :   {
303*cdf0e10cSrcweir                                     m_pFairRWLock->releaseReadAccess();
304*cdf0e10cSrcweir                                 }
305*cdf0e10cSrcweir                                 break;
306*cdf0e10cSrcweir     }
307*cdf0e10cSrcweir }
308*cdf0e10cSrcweir 
309*cdf0e10cSrcweir /*-************************************************************************************************************//**
310*cdf0e10cSrcweir     @interface  IRWLock
311*cdf0e10cSrcweir     @short      set lock for writing
312*cdf0e10cSrcweir     @descr      A guard should call this method to acquire write access on your member.
313*cdf0e10cSrcweir                 Reading is allowed too - of course.
314*cdf0e10cSrcweir                 After successfully calling of this method you are the only writer.
315*cdf0e10cSrcweir                 We use m_eLockType to differ between all possible "lock-member"!!!
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir     @attention  If a shareable osl mutex exist, he must be used as twice!
318*cdf0e10cSrcweir                 It's neccessary for some cppu-helper classes ...
319*cdf0e10cSrcweir 
320*cdf0e10cSrcweir     @seealso    method releaseWriteAccess()
321*cdf0e10cSrcweir 
322*cdf0e10cSrcweir     @param      -
323*cdf0e10cSrcweir     @return     -
324*cdf0e10cSrcweir 
325*cdf0e10cSrcweir     @onerror    -
326*cdf0e10cSrcweir *//*-*************************************************************************************************************/
327*cdf0e10cSrcweir void LockHelper::acquireWriteAccess()
328*cdf0e10cSrcweir {
329*cdf0e10cSrcweir     switch( m_eLockType )
330*cdf0e10cSrcweir     {
331*cdf0e10cSrcweir         case E_NOTHING      :   break; // There is nothing to do ...
332*cdf0e10cSrcweir         case E_OWNMUTEX     :   {
333*cdf0e10cSrcweir                                     m_pOwnMutex->acquire();
334*cdf0e10cSrcweir                                 }
335*cdf0e10cSrcweir                                 break;
336*cdf0e10cSrcweir         case E_SOLARMUTEX   :   {
337*cdf0e10cSrcweir                                     m_pSolarMutex->acquire();
338*cdf0e10cSrcweir                                 }
339*cdf0e10cSrcweir                                 break;
340*cdf0e10cSrcweir         case E_FAIRRWLOCK   :   {
341*cdf0e10cSrcweir                                     m_pFairRWLock->acquireWriteAccess();
342*cdf0e10cSrcweir                                 }
343*cdf0e10cSrcweir                                 break;
344*cdf0e10cSrcweir     }
345*cdf0e10cSrcweir }
346*cdf0e10cSrcweir 
347*cdf0e10cSrcweir /*-************************************************************************************************************//**
348*cdf0e10cSrcweir     @interface  IRWLock
349*cdf0e10cSrcweir     @short      reset lock for writing
350*cdf0e10cSrcweir     @descr      A guard should call this method to release write access on your member.
351*cdf0e10cSrcweir                 We use m_eLockType to differ between all possible "lock-member"!!!
352*cdf0e10cSrcweir 
353*cdf0e10cSrcweir     @attention  If a shareable osl mutex exist, he must be used as twice!
354*cdf0e10cSrcweir                 It's neccessary for some cppu-helper classes ...
355*cdf0e10cSrcweir 
356*cdf0e10cSrcweir     @seealso    method acquireWriteAccess()
357*cdf0e10cSrcweir 
358*cdf0e10cSrcweir     @param      -
359*cdf0e10cSrcweir     @return     -
360*cdf0e10cSrcweir 
361*cdf0e10cSrcweir     @onerror    -
362*cdf0e10cSrcweir *//*-*************************************************************************************************************/
363*cdf0e10cSrcweir void LockHelper::releaseWriteAccess()
364*cdf0e10cSrcweir {
365*cdf0e10cSrcweir     switch( m_eLockType )
366*cdf0e10cSrcweir     {
367*cdf0e10cSrcweir         case E_NOTHING      :   break; // There is nothing to do ...
368*cdf0e10cSrcweir         case E_OWNMUTEX     :   {
369*cdf0e10cSrcweir                                     m_pOwnMutex->release();
370*cdf0e10cSrcweir                                 }
371*cdf0e10cSrcweir                                 break;
372*cdf0e10cSrcweir         case E_SOLARMUTEX   :   {
373*cdf0e10cSrcweir                                     m_pSolarMutex->release();
374*cdf0e10cSrcweir                                 }
375*cdf0e10cSrcweir                                 break;
376*cdf0e10cSrcweir         case E_FAIRRWLOCK   :   {
377*cdf0e10cSrcweir                                     m_pFairRWLock->releaseWriteAccess();
378*cdf0e10cSrcweir                                 }
379*cdf0e10cSrcweir                                 break;
380*cdf0e10cSrcweir     }
381*cdf0e10cSrcweir }
382*cdf0e10cSrcweir 
383*cdf0e10cSrcweir /*-************************************************************************************************************//**
384*cdf0e10cSrcweir     @interface  IRWLock
385*cdf0e10cSrcweir     @short      downgrade a write access to a read access
386*cdf0e10cSrcweir     @descr      A guard should call this method to change a write to a read access.
387*cdf0e10cSrcweir                 New readers can work too - new writer are blocked!
388*cdf0e10cSrcweir                 We use m_eLockType to differ between all possible "lock-member"!!!
389*cdf0e10cSrcweir 
390*cdf0e10cSrcweir     @attention  Ignore shareable mutex(!) - because this call never should release a lock completly!
391*cdf0e10cSrcweir                 We change a write access to a read access only.
392*cdf0e10cSrcweir 
393*cdf0e10cSrcweir     @attention  a) Don't call this method if you are not a writer!
394*cdf0e10cSrcweir                     Results are not defined then ...
395*cdf0e10cSrcweir                     An upgrade can't be implemented realy ... because acquiring new access
396*cdf0e10cSrcweir                     will be the same - there no differences!
397*cdf0e10cSrcweir                 b) Without function if m_eLockTyp is different from E_FAIRRWLOCK(!) ...
398*cdf0e10cSrcweir                     because, a mutex don't support it realy.
399*cdf0e10cSrcweir 
400*cdf0e10cSrcweir     @seealso    -
401*cdf0e10cSrcweir 
402*cdf0e10cSrcweir     @param      -
403*cdf0e10cSrcweir     @return     -
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir     @onerror    -
406*cdf0e10cSrcweir *//*-*************************************************************************************************************/
407*cdf0e10cSrcweir void LockHelper::downgradeWriteAccess()
408*cdf0e10cSrcweir {
409*cdf0e10cSrcweir     switch( m_eLockType )
410*cdf0e10cSrcweir     {
411*cdf0e10cSrcweir         case E_NOTHING      :   break; // There is nothing to do ...
412*cdf0e10cSrcweir         case E_OWNMUTEX     :   break; // Not supported for mutex!
413*cdf0e10cSrcweir         case E_SOLARMUTEX   :   break; // Not supported for mutex!
414*cdf0e10cSrcweir         case E_FAIRRWLOCK   :   m_pFairRWLock->downgradeWriteAccess();
415*cdf0e10cSrcweir                                 break;
416*cdf0e10cSrcweir     }
417*cdf0e10cSrcweir }
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir /*-************************************************************************************************************//**
420*cdf0e10cSrcweir     @short      return a reference to a static lock helper
421*cdf0e10cSrcweir     @descr      Sometimes we need the global mutex or rw-lock! (e.g. in our own static methods)
422*cdf0e10cSrcweir                 But it's not a good idea to use these global one very often ...
423*cdf0e10cSrcweir                 Thats why we use this little helper method.
424*cdf0e10cSrcweir                 We create our own "class global static" lock.
425*cdf0e10cSrcweir                 It will be created at first call only!
426*cdf0e10cSrcweir                 All other requests use these created one then directly.
427*cdf0e10cSrcweir 
428*cdf0e10cSrcweir     @seealso    -
429*cdf0e10cSrcweir 
430*cdf0e10cSrcweir     @param      -
431*cdf0e10cSrcweir     @return     A reference to a static mutex/lock member.
432*cdf0e10cSrcweir 
433*cdf0e10cSrcweir     @onerror    No error should occure.
434*cdf0e10cSrcweir *//*-*************************************************************************************************************/
435*cdf0e10cSrcweir LockHelper& LockHelper::getGlobalLock( ::vos::IMutex* pSolarMutex )
436*cdf0e10cSrcweir {
437*cdf0e10cSrcweir     // Initialize static "member" only for one time!
438*cdf0e10cSrcweir     // Algorithm:
439*cdf0e10cSrcweir     // a) Start with an invalid lock (NULL pointer)
440*cdf0e10cSrcweir     // b) If these method first called (lock not already exist!) ...
441*cdf0e10cSrcweir     // c) ... we must create a new one. Protect follow code with the global mutex -
442*cdf0e10cSrcweir     //    (It must be - we create a static variable!)
443*cdf0e10cSrcweir     // d) Check pointer again - because ... another instance of our class could be faster then these one!
444*cdf0e10cSrcweir     // e) Create the new lock and set it for return on static variable.
445*cdf0e10cSrcweir     // f) Return new created or already existing lock object.
446*cdf0e10cSrcweir     static LockHelper* pLock = NULL;
447*cdf0e10cSrcweir     if( pLock == NULL )
448*cdf0e10cSrcweir     {
449*cdf0e10cSrcweir         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
450*cdf0e10cSrcweir         if( pLock == NULL )
451*cdf0e10cSrcweir         {
452*cdf0e10cSrcweir             static LockHelper aLock( pSolarMutex );
453*cdf0e10cSrcweir             pLock = &aLock;
454*cdf0e10cSrcweir         }
455*cdf0e10cSrcweir     }
456*cdf0e10cSrcweir     return *pLock;
457*cdf0e10cSrcweir }
458*cdf0e10cSrcweir 
459*cdf0e10cSrcweir /*-************************************************************************************************************//**
460*cdf0e10cSrcweir     @short      return a reference to shared mutex member
461*cdf0e10cSrcweir     @descr      Sometimes we need a osl-mutex for sharing with our uno helper ...
462*cdf0e10cSrcweir                 What can we do?
463*cdf0e10cSrcweir                 a) If we have an initialized "own mutex" ... we can use it!
464*cdf0e10cSrcweir                 b) Otherwhise we must use a different mutex member :-(
465*cdf0e10cSrcweir                 I HOPE IT WORKS!
466*cdf0e10cSrcweir 
467*cdf0e10cSrcweir     @seealso    -
468*cdf0e10cSrcweir 
469*cdf0e10cSrcweir     @param      -
470*cdf0e10cSrcweir     @return     A reference to a shared mutex.
471*cdf0e10cSrcweir 
472*cdf0e10cSrcweir     @onerror    No error should occure.
473*cdf0e10cSrcweir *//*-*************************************************************************************************************/
474*cdf0e10cSrcweir ::osl::Mutex& LockHelper::getShareableOslMutex()
475*cdf0e10cSrcweir {
476*cdf0e10cSrcweir     if( m_pShareableOslMutex == NULL )
477*cdf0e10cSrcweir     {
478*cdf0e10cSrcweir         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
479*cdf0e10cSrcweir         if( m_pShareableOslMutex == NULL )
480*cdf0e10cSrcweir         {
481*cdf0e10cSrcweir             switch( m_eLockType )
482*cdf0e10cSrcweir             {
483*cdf0e10cSrcweir                 case E_OWNMUTEX     :   {
484*cdf0e10cSrcweir                                             m_pShareableOslMutex = m_pOwnMutex;
485*cdf0e10cSrcweir                                         }
486*cdf0e10cSrcweir                                         break;
487*cdf0e10cSrcweir                 default             :   {
488*cdf0e10cSrcweir                                             m_pShareableOslMutex = new ::osl::Mutex;
489*cdf0e10cSrcweir                                         }
490*cdf0e10cSrcweir                                         break;
491*cdf0e10cSrcweir             }
492*cdf0e10cSrcweir         }
493*cdf0e10cSrcweir     }
494*cdf0e10cSrcweir     return *m_pShareableOslMutex;
495*cdf0e10cSrcweir }
496*cdf0e10cSrcweir 
497*cdf0e10cSrcweir /*-************************************************************************************************************//**
498*cdf0e10cSrcweir     @short      search for right lock type, which should be used by an instance of this struct
499*cdf0e10cSrcweir     @descr      We must initialize our member "m_eLockType". This value specify handling of locking.
500*cdf0e10cSrcweir                 How we can do that? We search for an environment variable. We do it only for one time ....
501*cdf0e10cSrcweir                 because the environment is fix. So we safe this value and use it for all further requests.
502*cdf0e10cSrcweir                 If no variable could be found - we use a fallback!
503*cdf0e10cSrcweir 
504*cdf0e10cSrcweir     @attention  We have numbered all our enum values for ELockType. So we can use it as value of searched
505*cdf0e10cSrcweir                 environment variable too!
506*cdf0e10cSrcweir 
507*cdf0e10cSrcweir     @seealso    enum ELockType
508*cdf0e10cSrcweir     @seealso    environment LOCKTYPE
509*cdf0e10cSrcweir 
510*cdf0e10cSrcweir     @param      -
511*cdf0e10cSrcweir     @return     A reference to a created and right initialized lock type!
512*cdf0e10cSrcweir 
513*cdf0e10cSrcweir     @onerror    We use a fallback!
514*cdf0e10cSrcweir *//*-*************************************************************************************************************/
515*cdf0e10cSrcweir ELockType& LockHelper::implts_getLockType()
516*cdf0e10cSrcweir {
517*cdf0e10cSrcweir     // Initialize static "member" only for one time!
518*cdf0e10cSrcweir     // Algorithm:
519*cdf0e10cSrcweir     // a) Start with an invalid variable (NULL pointer)
520*cdf0e10cSrcweir     // b) If these method first called (value not already exist!) ...
521*cdf0e10cSrcweir     // c) ... we must create a new one. Protect follow code with the global mutex -
522*cdf0e10cSrcweir     //    (It must be - we create a static variable!)
523*cdf0e10cSrcweir     // d) Check pointer again - because ... another instance of our class could be faster then these one!
524*cdf0e10cSrcweir     // e) Create the new static variable, get value from the environment and set it
525*cdf0e10cSrcweir     // f) Return new created or already existing static variable.
526*cdf0e10cSrcweir     static ELockType* pType = NULL;
527*cdf0e10cSrcweir     if( pType == NULL )
528*cdf0e10cSrcweir     {
529*cdf0e10cSrcweir         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
530*cdf0e10cSrcweir         if( pType == NULL )
531*cdf0e10cSrcweir         {
532*cdf0e10cSrcweir             static ELockType eType = FALLBACK_LOCKTYPE;
533*cdf0e10cSrcweir 
534*cdf0e10cSrcweir             ::vos::OStartupInfo aEnvironment;
535*cdf0e10cSrcweir             ::rtl::OUString     sValue      ;
536*cdf0e10cSrcweir             if( aEnvironment.getEnvironment( ENVVAR_LOCKTYPE, sValue ) == ::vos::OStartupInfo::E_None )
537*cdf0e10cSrcweir             {
538*cdf0e10cSrcweir                 eType = (ELockType)(sValue.toInt32());
539*cdf0e10cSrcweir             }
540*cdf0e10cSrcweir 
541*cdf0e10cSrcweir             LOG_LOCKTYPE( FALLBACK_LOCKTYPE, eType )
542*cdf0e10cSrcweir 
543*cdf0e10cSrcweir             pType = &eType;
544*cdf0e10cSrcweir         }
545*cdf0e10cSrcweir     }
546*cdf0e10cSrcweir     return *pType;
547*cdf0e10cSrcweir }
548*cdf0e10cSrcweir 
549*cdf0e10cSrcweir } //  namespace framework
550