1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef __FRAMEWORK_THREADHELP_LOCKHELPER_HXX_
25 #define __FRAMEWORK_THREADHELP_LOCKHELPER_HXX_
26 
27 //_________________________________________________________________________________________________________________
28 //	my own includes
29 //_________________________________________________________________________________________________________________
30 
31 #include <threadhelp/inoncopyable.h>
32 #include <framework/imutex.hxx>
33 #include <threadhelp/irwlock.h>
34 #include <threadhelp/fairrwlock.hxx>
35 
36 //_________________________________________________________________________________________________________________
37 //	interface includes
38 //_________________________________________________________________________________________________________________
39 
40 //_________________________________________________________________________________________________________________
41 //	other includes
42 //_________________________________________________________________________________________________________________
43 #include <osl/mutex.hxx>
44 #include <vos/mutex.hxx>
45 #include <fwidllapi.h>
46 
47 //_________________________________________________________________________________________________________________
48 //	namespace
49 //_________________________________________________________________________________________________________________
50 
51 namespace framework{
52 
53 //_________________________________________________________________________________________________________________
54 //	const
55 //_________________________________________________________________________________________________________________
56 
57 /*-************************************************************************************************************//**
58 	@descr			If you use a lock or mutex as a member of your class and wish to use it earlier than other ones
59 					you should have a look on this implementation. You must use it as the first base class
60 					of your implementation - because base classes are initialized by his order and before your
61 					member! That's why it is a good place to declare your thread help member so.
62 *//*-*************************************************************************************************************/
63 enum ELockType
64 {
65 	E_NOTHING		= 0 ,
66 	E_OWNMUTEX		= 1 ,
67 	E_SOLARMUTEX	= 2 ,
68 	E_FAIRRWLOCK	= 3
69 };
70 
71 #define ENVVAR_LOCKTYPE		DECLARE_ASCII("LOCKTYPE_FRAMEWORK")
72 #define FALLBACK_LOCKTYPE	E_SOLARMUTEX
73 
74 //_________________________________________________________________________________________________________________
75 // declarations
76 //_________________________________________________________________________________________________________________
77 
78 /*-************************************************************************************************************//**
79     @short          helper to set right lock in right situation
80     @descr          This helper support different types of locking:
81                         a)  no locks - transparent for user!
82                             This could be useful for simulation or single threaded environments!
83                         b)  own mutex
84                             An object use his own osl-mutex to be threadsafe. Useful for easy and exclusive locking.
85                         c)  solar mutex
86                             An object use our solar mutex and will be a part of a greater saved "threadsafe code block".
87                             Could be useful for simulation and testing of higher modules!
88                         d)  fair rw-lock
89                             An object use an implementation of a fair rw-lock. This increase granularity of threadsafe mechanism
90                             and should be used for high performance threadsafe code!
91 
92     @attention      We support two interfaces - "IMutex" and "IRWLock". Don't mix using of it!
93                     A guard implementation should use one interface only!
94 
95     @implements     IMutex
96     @implements     IRWLock
97 
98     @base           INonCopyable
99                     IMutex
100                     IRWLock
101 
102     @devstatus      draft
103 *//*-*************************************************************************************************************/
104 class FWI_DLLPUBLIC LockHelper : public  IMutex
105                  , public  IRWLock
106                  , private INonCopyable
107 {
108 	//-------------------------------------------------------------------------------------------------------------
109 	//	public methods
110 	//-------------------------------------------------------------------------------------------------------------
111 	public:
112 
113         //-------------------------------------------------------------------------------------------------------------
114         //  ctor/dtor
115         //-------------------------------------------------------------------------------------------------------------
116                  LockHelper( ::vos::IMutex* pSolarMutex = NULL );
117         virtual ~LockHelper(                                   );
118 
119         //-------------------------------------------------------------------------------------------------------------
120         //  interface ::framework::IMutex
121         //-------------------------------------------------------------------------------------------------------------
122         virtual void acquire();
123         virtual void release();
124 
125         //-------------------------------------------------------------------------------------------------------------
126         //  interface ::framework::IRWLock
127         //-------------------------------------------------------------------------------------------------------------
128         virtual void acquireReadAccess   ();
129         virtual void releaseReadAccess   ();
130         virtual void acquireWriteAccess  ();
131         virtual void releaseWriteAccess  ();
132         virtual void downgradeWriteAccess();
133 
134         //-------------------------------------------------------------------------------------------------------------
135         //  something else
136         //-------------------------------------------------------------------------------------------------------------
137         static LockHelper&  getGlobalLock       ( ::vos::IMutex* pSolarMutex = NULL );
138         ::osl::Mutex&       getShareableOslMutex(                                   );
139 
140 	//-------------------------------------------------------------------------------------------------------------
141 	//  private methods
142 	//-------------------------------------------------------------------------------------------------------------
143     private:
144 
145         static ELockType& implts_getLockType();
146 
147 	//-------------------------------------------------------------------------------------------------------------
148 	//  private member
149 	//  a) Make some member mutable for using in const functions!
150 	//  b) "m_eLockType" define, which of follow members is used!
151 	//     You can use "m_pFairRWLock" as a fair rw-lock (multiple reader / one writer / looks for incoming order of threads too) ...
152 	//     or you can use a normal osl mutex ("m_pOwnMutex") ...
153 	//     ... or the solarmuex as "m_pSolarMutex" (must be set from outside! because some components must be vcl-free!)
154 	//     ... but sometimes you need a shareable osl mutex!
155 	//     In this case you has some problems: i  ) If your lock type is set to E_OWNMUTEX => it's easy; you can use your member "m_pOwnMutex" - it's a osl mutex.
156 	//                                              Creation and use of "m_pShareableOslMutex" isn't necessary!
157 	//                                         ii ) Otherwise you have no osl mutex ... so you must create "m_pShareableOslMutex" and use it twice!
158 	//                                              In this case you must lock two members every time - "m_pShareableMutex" AND "m_pFairRWLock" or "m_pSolarMutex" or ...
159 	//                                              It isn't really fine - but the only possible way.
160 	//                                         iii) There exists another special case - E_NOTHING is set! Then we should create this shareable mutex ...
161 	//                                              and you can use it ... but this implementation ignores it.
162 	//-------------------------------------------------------------------------------------------------------------
163     private:
164 
165         ELockType               m_eLockType             ;
166 
167         mutable FairRWLock*     m_pFairRWLock           ;
168         mutable ::osl::Mutex*   m_pOwnMutex             ;
169         mutable ::vos::IMutex*  m_pSolarMutex           ;
170         mutable ::osl::Mutex*   m_pShareableOslMutex    ;
171         mutable sal_Bool        m_bDummySolarMutex      ;
172 };
173 
174 }		// namespace framework
175 
176 #endif  //  #ifndef __FRAMEWORK_THREADHELP_LOCKHELPER_HXX_
177