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 #ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_
29*cdf0e10cSrcweir #define __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
32*cdf0e10cSrcweir //	my own includes
33*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir #include <threadhelp/inoncopyable.h>
36*cdf0e10cSrcweir #include <threadhelp/irwlock.h>
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir //#ifndef __FRAMEWORK_THREADHELP_THREADHELPBASE_HXX_
39*cdf0e10cSrcweir //#include <threadhelp/threadhelpbase.hxx>
40*cdf0e10cSrcweir //#endif
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
43*cdf0e10cSrcweir //	interface includes
44*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
47*cdf0e10cSrcweir //	other includes
48*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
51*cdf0e10cSrcweir //	namespace
52*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir namespace framework{
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
57*cdf0e10cSrcweir //	const
58*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
61*cdf0e10cSrcweir //	declarations
62*cdf0e10cSrcweir //_________________________________________________________________________________________________________________
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir /*-************************************************************************************************************//**
65*cdf0e10cSrcweir 	@short          implement a guard to set write locks
66*cdf0e10cSrcweir 	@descr			This guard should be used to set a lock for reading AND writing object internal member.
67*cdf0e10cSrcweir 					We never need a own mutex to safe our internal member access - because
68*cdf0e10cSrcweir 					a guard is used as function-local member only. There exist no multithreaded access to it realy ...
69*cdf0e10cSrcweir 
70*cdf0e10cSrcweir     @attention      a) To prevent us against wrong using, the default ctor, copy ctor and the =operator are maked private!
71*cdf0e10cSrcweir                     b) Use interface "IRWLock" of set LockHelper only - because we must support a finer granularity of locking.
72*cdf0e10cSrcweir                        Interface "IMutex" should be used by easier guard implementations ... like "ResetableGuard"!
73*cdf0e10cSrcweir 
74*cdf0e10cSrcweir 	@implements		-
75*cdf0e10cSrcweir     @base           INonCopyable
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir 	@devstatus		ready to use
78*cdf0e10cSrcweir *//*-*************************************************************************************************************/
79*cdf0e10cSrcweir class WriteGuard : private INonCopyable
80*cdf0e10cSrcweir {
81*cdf0e10cSrcweir 	//-------------------------------------------------------------------------------------------------------------
82*cdf0e10cSrcweir 	//	public methods
83*cdf0e10cSrcweir 	//-------------------------------------------------------------------------------------------------------------
84*cdf0e10cSrcweir 	public:
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir         /*-****************************************************************************************************//**
87*cdf0e10cSrcweir             @short      ctor
88*cdf0e10cSrcweir             @descr      These ctors initialize the guard with a reference to used lock member of object to protect.
89*cdf0e10cSrcweir                         Null isn't allowed as value!
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir             @seealso    -
92*cdf0e10cSrcweir 
93*cdf0e10cSrcweir             @param      "pLock" ,reference to used lock member of object to protect
94*cdf0e10cSrcweir             @param      "rLock" ,reference to used lock member of object to protect
95*cdf0e10cSrcweir             @return     -
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir             @onerror    -
98*cdf0e10cSrcweir         *//*-*****************************************************************************************************/
99*cdf0e10cSrcweir         inline WriteGuard( IRWLock* pLock )
100*cdf0e10cSrcweir             :   m_pLock ( pLock     )
101*cdf0e10cSrcweir             ,   m_eMode ( E_NOLOCK  )
102*cdf0e10cSrcweir         {
103*cdf0e10cSrcweir             lock();
104*cdf0e10cSrcweir         }
105*cdf0e10cSrcweir 
106*cdf0e10cSrcweir         //*********************************************************************************************************
107*cdf0e10cSrcweir         inline WriteGuard( IRWLock& rLock )
108*cdf0e10cSrcweir             :   m_pLock ( &rLock    )
109*cdf0e10cSrcweir             ,   m_eMode ( E_NOLOCK  )
110*cdf0e10cSrcweir         {
111*cdf0e10cSrcweir             lock();
112*cdf0e10cSrcweir         }
113*cdf0e10cSrcweir 
114*cdf0e10cSrcweir         /*-****************************************************************************************************//**
115*cdf0e10cSrcweir             @short      dtor
116*cdf0e10cSrcweir             @descr      We unlock the used lock member automaticly if user forget it.
117*cdf0e10cSrcweir 
118*cdf0e10cSrcweir             @seealso    -
119*cdf0e10cSrcweir 
120*cdf0e10cSrcweir             @param      -
121*cdf0e10cSrcweir             @return     -
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir             @onerror    -
124*cdf0e10cSrcweir         *//*-*****************************************************************************************************/
125*cdf0e10cSrcweir         inline ~WriteGuard()
126*cdf0e10cSrcweir         {
127*cdf0e10cSrcweir             unlock();
128*cdf0e10cSrcweir         }
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir         /*-****************************************************************************************************//**
131*cdf0e10cSrcweir             @short      set write lock
132*cdf0e10cSrcweir             @descr      Call this method to set the write lock. The call will block till all current threads are synchronized!
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir             @seealso    method unlock()
135*cdf0e10cSrcweir 
136*cdf0e10cSrcweir             @param      -
137*cdf0e10cSrcweir             @return     -
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir             @onerror    -
140*cdf0e10cSrcweir         *//*-*****************************************************************************************************/
141*cdf0e10cSrcweir         inline void lock()
142*cdf0e10cSrcweir         {
143*cdf0e10cSrcweir             switch( m_eMode )
144*cdf0e10cSrcweir             {
145*cdf0e10cSrcweir                 case E_NOLOCK       :   {
146*cdf0e10cSrcweir                                             // Acquire write access and set return state.
147*cdf0e10cSrcweir                                             // Mode is set later if it was successful!
148*cdf0e10cSrcweir                                             m_pLock->acquireWriteAccess();
149*cdf0e10cSrcweir                                             m_eMode = E_WRITELOCK;
150*cdf0e10cSrcweir                                         }
151*cdf0e10cSrcweir                                         break;
152*cdf0e10cSrcweir                 case E_READLOCK     :   {
153*cdf0e10cSrcweir                                             // User has downgrade to read access before!
154*cdf0e10cSrcweir                                             // We must release it before we can set a new write access!
155*cdf0e10cSrcweir                                             m_pLock->releaseReadAccess();
156*cdf0e10cSrcweir                                             m_pLock->acquireWriteAccess();
157*cdf0e10cSrcweir                                             m_eMode = E_WRITELOCK;
158*cdf0e10cSrcweir                                         }
159*cdf0e10cSrcweir                                         break;
160*cdf0e10cSrcweir                 default:                break; // nothing to do
161*cdf0e10cSrcweir             }
162*cdf0e10cSrcweir         }
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir         /*-****************************************************************************************************//**
165*cdf0e10cSrcweir             @short      unset write lock
166*cdf0e10cSrcweir             @descr      Call this method to unlock the rw-lock temp.!
167*cdf0e10cSrcweir                         Normaly we do it at dtor automaticly for you ...
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir             @seealso    method lock()
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir             @param      -
172*cdf0e10cSrcweir             @return     -
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir             @onerror    -
175*cdf0e10cSrcweir         *//*-*****************************************************************************************************/
176*cdf0e10cSrcweir         inline void unlock()
177*cdf0e10cSrcweir         {
178*cdf0e10cSrcweir             switch( m_eMode )
179*cdf0e10cSrcweir             {
180*cdf0e10cSrcweir                 case E_READLOCK     :   {
181*cdf0e10cSrcweir                                             // User has downgraded to a read lock before!
182*cdf0e10cSrcweir                                             // => There isn't realy a write lock ...
183*cdf0e10cSrcweir                                             m_pLock->releaseReadAccess();
184*cdf0e10cSrcweir                                             m_eMode = E_NOLOCK;
185*cdf0e10cSrcweir                                         }
186*cdf0e10cSrcweir                                         break;
187*cdf0e10cSrcweir                 case E_WRITELOCK    :   {
188*cdf0e10cSrcweir                                             m_pLock->releaseWriteAccess();
189*cdf0e10cSrcweir                                             m_eMode = E_NOLOCK;
190*cdf0e10cSrcweir                                         }
191*cdf0e10cSrcweir                                         break;
192*cdf0e10cSrcweir                 default:                break; // nothing to do
193*cdf0e10cSrcweir             }
194*cdf0e10cSrcweir         }
195*cdf0e10cSrcweir 
196*cdf0e10cSrcweir         /*-****************************************************************************************************//**
197*cdf0e10cSrcweir             @short      downgrade write access to read access without new blocking!
198*cdf0e10cSrcweir             @descr      If this write lock is set you can change it to a "read lock".
199*cdf0e10cSrcweir                         An "upgrade" is the same like new calling "lock()"!
200*cdf0e10cSrcweir 
201*cdf0e10cSrcweir             @seealso    -
202*cdf0e10cSrcweir 
203*cdf0e10cSrcweir             @param      -
204*cdf0e10cSrcweir             @return     -
205*cdf0e10cSrcweir 
206*cdf0e10cSrcweir             @onerror    -
207*cdf0e10cSrcweir         *//*-*****************************************************************************************************/
208*cdf0e10cSrcweir         inline void downgrade()
209*cdf0e10cSrcweir         {
210*cdf0e10cSrcweir             if( m_eMode == E_WRITELOCK )
211*cdf0e10cSrcweir             {
212*cdf0e10cSrcweir                 m_pLock->downgradeWriteAccess();
213*cdf0e10cSrcweir                 m_eMode = E_READLOCK;
214*cdf0e10cSrcweir             }
215*cdf0e10cSrcweir         }
216*cdf0e10cSrcweir 
217*cdf0e10cSrcweir         /*-****************************************************************************************************//**
218*cdf0e10cSrcweir             @short      return internal states
219*cdf0e10cSrcweir             @descr      For user they dont know what they are doing ...
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir             @seealso    -
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir             @param      -
224*cdf0e10cSrcweir             @return     Current set lock mode.
225*cdf0e10cSrcweir 
226*cdf0e10cSrcweir             @onerror    No error should occure.
227*cdf0e10cSrcweir         *//*-*****************************************************************************************************/
228*cdf0e10cSrcweir         inline ELockMode getMode() const
229*cdf0e10cSrcweir         {
230*cdf0e10cSrcweir             return m_eMode;
231*cdf0e10cSrcweir         }
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir 	//-------------------------------------------------------------------------------------------------------------
234*cdf0e10cSrcweir 	//	private methods
235*cdf0e10cSrcweir 	//-------------------------------------------------------------------------------------------------------------
236*cdf0e10cSrcweir 	private:
237*cdf0e10cSrcweir 
238*cdf0e10cSrcweir 		/*-****************************************************************************************************//**
239*cdf0e10cSrcweir 			@short		disable using of these functions!
240*cdf0e10cSrcweir 			@descr		It's not allowed to use this methods. Different problem can occure otherwise.
241*cdf0e10cSrcweir 						Thats why we disable it by make it private.
242*cdf0e10cSrcweir 
243*cdf0e10cSrcweir 			@seealso	other ctor
244*cdf0e10cSrcweir 
245*cdf0e10cSrcweir 			@param		-
246*cdf0e10cSrcweir 			@return		-
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir 			@onerror	-
249*cdf0e10cSrcweir 		*//*-*****************************************************************************************************/
250*cdf0e10cSrcweir 		WriteGuard();
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir 	//-------------------------------------------------------------------------------------------------------------
253*cdf0e10cSrcweir 	//	private member
254*cdf0e10cSrcweir 	//-------------------------------------------------------------------------------------------------------------
255*cdf0e10cSrcweir 	private:
256*cdf0e10cSrcweir 
257*cdf0e10cSrcweir         IRWLock*    m_pLock ;   /// reference to lock-member of protected object
258*cdf0e10cSrcweir 		ELockMode	m_eMode	;	/// protection against multiple lock calls without unlock and difference between supported lock modi
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir };		//	class WriteGuard
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir }       //  namespace framework
263*cdf0e10cSrcweir 
264*cdf0e10cSrcweir #endif	//	#ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_
265