xref: /trunk/main/sal/inc/osl/mutex.hxx (revision 565d668c)
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 _OSL_MUTEX_HXX_
25 #define _OSL_MUTEX_HXX_
26 
27 #ifdef __cplusplus
28 
29 #include <osl/mutex.h>
30 
31 
32 namespace osl
33 {
34     /** A mutual exclusion synchronization object
35     */
36 	class Mutex {
37 
38     public:
39 		/** Create a thread-local mutex.
40 			@return 0 if the mutex could not be created, otherwise a handle to the mutex.
41             @seealso ::osl_createMutex()
42 		*/
Mutex()43 		Mutex()
44 		{
45 			mutex = osl_createMutex();
46 		}
47 
48 		/** Release the OS-structures and free mutex data-structure.
49             @seealso ::osl_destroyMutex()
50 		*/
~Mutex()51 		~Mutex()
52 		{
53 			osl_destroyMutex(mutex);
54 		}
55 
56 		/** Acquire the mutex, block if already acquired by another thread.
57 			@return sal_False if system-call fails.
58             @seealso ::osl_acquireMutex()
59 		*/
acquire()60 		sal_Bool acquire()
61 		{
62 			return osl_acquireMutex(mutex);
63 		}
64 
65 		/** Try to acquire the mutex without blocking.
66 			@return sal_False if it could not be acquired.
67             @seealso ::osl_tryToAcquireMutex()
68 		*/
tryToAcquire()69 		sal_Bool tryToAcquire()
70 		{
71 			return osl_tryToAcquireMutex(mutex);
72 		}
73 
74 		/** Release the mutex.
75 			@return sal_False if system-call fails.
76             @seealso ::osl_releaseMutex()
77 		*/
release()78 		sal_Bool release()
79 		{
80 			return osl_releaseMutex(mutex);
81 		}
82 
83         /** Returns a global static mutex object.
84             The global and static mutex object can be used to initialize other
85             static objects in a thread safe manner.
86             @return the global mutex object
87             @seealso ::osl_getGlobalMutex()
88         */
getGlobalMutex()89 		static Mutex * getGlobalMutex()
90 		{
91 			return (Mutex *)osl_getGlobalMutex();
92 		}
93 
94 	private:
95         oslMutex mutex;
96 
97         /** The underlying oslMutex has no reference count.
98 
99         Since the underlying oslMutex is not a reference counted object, copy
100         constructed Mutex may work on an already destructed oslMutex object.
101 
102         */
103         Mutex(const Mutex&);
104 
105         /** The underlying oslMutex has no reference count.
106 
107         When destructed, the Mutex object destroys the undelying oslMutex,
108         which might cause severe problems in case it's a temporary object.
109 
110         */
111         Mutex(oslMutex Mutex);
112 
113         /** This assignment operator is private for the same reason as
114             the copy constructor.
115         */
116         Mutex& operator= (const Mutex&);
117 
118         /** This assignment operator is private for the same reason as
119             the constructor taking a oslMutex argument.
120         */
121         Mutex& operator= (oslMutex);
122 	};
123 
124     /** A helper class for mutex objects and interfaces.
125     */
126 	template<class T>
127 	class Guard
128 	{
129 	private:
130 		Guard( const Guard& );
131 		const Guard& operator = ( const Guard& );
132 
133 	protected:
134 		T * pT;
135 	public:
136 
137         /** Acquires the object specified as parameter.
138         */
Guard(T * pT_)139 		Guard(T * pT_) : pT(pT_)
140 		{
141 			pT->acquire();
142 		}
143 
144         /** Acquires the object specified as parameter.
145         */
Guard(T & t)146 		Guard(T & t) : pT(&t)
147 		{
148 			pT->acquire();
149 		}
150 
151 		/** Releases the mutex or interface. */
~Guard()152 		~Guard()
153 		{
154 			pT->release();
155 		}
156 	};
157 
158     /** A helper class for mutex objects and interfaces.
159     */
160 	template<class T>
161 	class ClearableGuard
162 	{
163 	private:
164 		ClearableGuard( const ClearableGuard& );
165 		const ClearableGuard& operator = ( const ClearableGuard& );
166 	protected:
167 		T * pT;
168 	public:
169 
170         /** Acquires the object specified as parameter.
171         */
ClearableGuard(T * pT_)172 		ClearableGuard(T * pT_) : pT(pT_)
173 		{
174 			pT->acquire();
175 		}
176 
177         /** Acquires the object specified as parameter.
178         */
ClearableGuard(T & t)179 		ClearableGuard(T & t) : pT(&t)
180 		{
181 			pT->acquire();
182 		}
183 
184 		/** Releases the mutex or interface if not already released by clear().
185         */
~ClearableGuard()186 		~ClearableGuard()
187 		{
188 			if (pT)
189 				pT->release();
190 		}
191 
192 		/** Releases the mutex or interface.
193         */
clear()194 		void clear()
195 		{
196 			if(pT)
197 			{
198 				pT->release();
199 				pT = NULL;
200 			}
201 	    }
202 	};
203 
204     /** A helper class for mutex objects and interfaces.
205     */
206 	template< class T >
207     class ResettableGuard : public ClearableGuard< T >
208     {
209     private:
210         ResettableGuard(ResettableGuard &); // not defined
211         void operator =(ResettableGuard &); // not defined
212 
213     protected:
214         T* pResetT;
215     public:
216         /** Acquires the object specified as parameter.
217         */
ResettableGuard(T * pT_)218         ResettableGuard( T* pT_ ) :
219                 ClearableGuard<T>( pT_ ),
220                 pResetT( pT_ )
221         {}
222 
223         /** Acquires the object specified as parameter.
224         */
ResettableGuard(T & rT)225         ResettableGuard( T& rT ) :
226                 ClearableGuard<T>( rT ),
227                 pResetT( &rT )
228         {}
229 
230 		/** Re-aquires the mutex or interface.
231         */
reset()232         void reset()
233         {
234             if( pResetT )
235             {
236                 this->pT = pResetT;
237                 this->pT->acquire();
238             }
239         }
240     };
241 
242 	typedef Guard<Mutex> MutexGuard;
243 	typedef ClearableGuard<Mutex> ClearableMutexGuard;
244 	typedef ResettableGuard< Mutex > ResettableMutexGuard;
245 }
246 
247 #endif  /* __cplusplus */
248 #endif	/* _OSL_MUTEX_HXX_ */
249 
250