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