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