xref: /AOO41X/main/sal/inc/osl/mutex.hxx (revision 565d668c30d8a6cacc881c774c5068be5401257d)
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