xref: /aoo41x/main/sal/inc/osl/mutex.hxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef _OSL_MUTEX_HXX_
29 #define _OSL_MUTEX_HXX_
30 
31 #ifdef __cplusplus
32 
33 #include <osl/mutex.h>
34 
35 
36 namespace osl
37 {
38     /** A mutual exclusion synchronization object
39     */
40 	class Mutex {
41 
42     public:
43 		/** Create a thread-local mutex.
44 			@return 0 if the mutex could not be created, otherwise a handle to the mutex.
45             @seealso ::osl_createMutex()
46 		*/
47 		Mutex()
48 		{
49 			mutex = osl_createMutex();
50 		}
51 
52 		/** Release the OS-structures and free mutex data-structure.
53             @seealso ::osl_destroyMutex()
54 		*/
55 		~Mutex()
56 		{
57 			osl_destroyMutex(mutex);
58 		}
59 
60 		/** Acquire the mutex, block if already acquired by another thread.
61 			@return sal_False if system-call fails.
62             @seealso ::osl_acquireMutex()
63 		*/
64 		sal_Bool acquire()
65 		{
66 			return osl_acquireMutex(mutex);
67 		}
68 
69 		/** Try to acquire the mutex without blocking.
70 			@return sal_False if it could not be acquired.
71             @seealso ::osl_tryToAcquireMutex()
72 		*/
73 		sal_Bool tryToAcquire()
74 		{
75 			return osl_tryToAcquireMutex(mutex);
76 		}
77 
78 		/** Release the mutex.
79 			@return sal_False if system-call fails.
80             @seealso ::osl_releaseMutex()
81 		*/
82 		sal_Bool release()
83 		{
84 			return osl_releaseMutex(mutex);
85 		}
86 
87         /** Returns a global static mutex object.
88             The global and static mutex object can be used to initialize other
89             static objects in a thread safe manner.
90             @return the global mutex object
91             @seealso ::osl_getGlobalMutex()
92         */
93 		static Mutex * getGlobalMutex()
94 		{
95 			return (Mutex *)osl_getGlobalMutex();
96 		}
97 
98 	private:
99         oslMutex mutex;
100 
101         /** The underlying oslMutex has no reference count.
102 
103         Since the underlying oslMutex is not a reference counted object, copy
104         constructed Mutex may work on an already destructed oslMutex object.
105 
106         */
107         Mutex(const Mutex&);
108 
109         /** The underlying oslMutex has no reference count.
110 
111         When destructed, the Mutex object destroys the undelying oslMutex,
112         which might cause severe problems in case it's a temporary object.
113 
114         */
115         Mutex(oslMutex Mutex);
116 
117         /** This assignment operator is private for the same reason as
118             the copy constructor.
119         */
120         Mutex& operator= (const Mutex&);
121 
122         /** This assignment operator is private for the same reason as
123             the constructor taking a oslMutex argument.
124         */
125         Mutex& operator= (oslMutex);
126 	};
127 
128     /** A helper class for mutex objects and interfaces.
129     */
130 	template<class T>
131 	class Guard
132 	{
133 	private:
134 		Guard( const Guard& );
135 		const Guard& operator = ( const Guard& );
136 
137 	protected:
138 		T * pT;
139 	public:
140 
141         /** Acquires the object specified as parameter.
142         */
143 		Guard(T * pT_) : pT(pT_)
144 		{
145 			pT->acquire();
146 		}
147 
148         /** Acquires the object specified as parameter.
149         */
150 		Guard(T & t) : pT(&t)
151 		{
152 			pT->acquire();
153 		}
154 
155 		/** Releases the mutex or interface. */
156 		~Guard()
157 		{
158 			pT->release();
159 		}
160 	};
161 
162     /** A helper class for mutex objects and interfaces.
163     */
164 	template<class T>
165 	class ClearableGuard
166 	{
167 	private:
168 		ClearableGuard( const ClearableGuard& );
169 		const ClearableGuard& operator = ( const ClearableGuard& );
170 	protected:
171 		T * pT;
172 	public:
173 
174         /** Acquires the object specified as parameter.
175         */
176 		ClearableGuard(T * pT_) : pT(pT_)
177 		{
178 			pT->acquire();
179 		}
180 
181         /** Acquires the object specified as parameter.
182         */
183 		ClearableGuard(T & t) : pT(&t)
184 		{
185 			pT->acquire();
186 		}
187 
188 		/** Releases the mutex or interface if not already released by clear().
189         */
190 		~ClearableGuard()
191 		{
192 			if (pT)
193 				pT->release();
194 		}
195 
196 		/** Releases the mutex or interface.
197         */
198 		void clear()
199 		{
200 			if(pT)
201 			{
202 				pT->release();
203 				pT = NULL;
204 			}
205 	    }
206 	};
207 
208     /** A helper class for mutex objects and interfaces.
209     */
210 	template< class T >
211     class ResettableGuard : public ClearableGuard< T >
212     {
213     private:
214         ResettableGuard(ResettableGuard &); // not defined
215         void operator =(ResettableGuard &); // not defined
216 
217     protected:
218         T* pResetT;
219     public:
220         /** Acquires the object specified as parameter.
221         */
222         ResettableGuard( T* pT_ ) :
223                 ClearableGuard<T>( pT_ ),
224                 pResetT( pT_ )
225         {}
226 
227         /** Acquires the object specified as parameter.
228         */
229         ResettableGuard( T& rT ) :
230                 ClearableGuard<T>( rT ),
231                 pResetT( &rT )
232         {}
233 
234 		/** Re-aquires the mutex or interface.
235         */
236         void reset()
237         {
238             if( pResetT )
239             {
240                 this->pT = pResetT;
241                 this->pT->acquire();
242             }
243         }
244     };
245 
246 	typedef Guard<Mutex> MutexGuard;
247 	typedef ClearableGuard<Mutex> ClearableMutexGuard;
248 	typedef ResettableGuard< Mutex > ResettableMutexGuard;
249 }
250 
251 #endif  /* __cplusplus */
252 #endif	/* _OSL_MUTEX_HXX_ */
253 
254