1 //===-- Mutex.h -------------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef liblldb_Mutex_h_ 11 #define liblldb_Mutex_h_ 12 #if defined(__cplusplus) 13 14 #include <pthread.h> 15 #include <assert.h> 16 17 #ifdef LLDB_CONFIGURATION_DEBUG 18 #include <string> 19 #endif 20 21 namespace lldb_private { 22 23 //---------------------------------------------------------------------- 24 /// @class Mutex Mutex.h "lldb/Host/Mutex.h" 25 /// @brief A C++ wrapper class for pthread mutexes. 26 //---------------------------------------------------------------------- 27 class Mutex 28 { 29 public: 30 friend class Locker; 31 friend class Condition; 32 33 enum Type 34 { 35 eMutexTypeNormal, ///< Mutex that can't recursively entered by the same thread 36 eMutexTypeRecursive ///< Mutex can be recursively entered by the same thread 37 }; 38 39 //------------------------------------------------------------------ 40 /// @class Mutex::Locker 41 /// 42 /// A scoped locking class that allows a variety of pthread mutex 43 /// objects to have a mutex locked when an Mutex::Locker 44 /// object is created, and unlocked when it goes out of scope or 45 /// when the Mutex::Locker::Reset(pthread_mutex_t *) 46 /// is called. This provides an exception safe way to lock a mutex 47 /// in a scope. 48 //------------------------------------------------------------------ 49 class Locker 50 { 51 public: 52 //-------------------------------------------------------------- 53 /// Default constructor. 54 /// 55 /// This will create a scoped mutex locking object that doesn't 56 /// have a mutex to lock. One will need to be provided using the 57 /// Mutex::Locker::Reset(pthread_mutex_t *) method. 58 /// 59 /// @see Mutex::Locker::Reset(pthread_mutex_t *) 60 //-------------------------------------------------------------- 61 Locker(); 62 63 //-------------------------------------------------------------- 64 /// Constructor with a Mutex object. 65 /// 66 /// This will create a scoped mutex locking object that extracts 67 /// the mutex owned by \a m and locks it. 68 /// 69 /// @param[in] m 70 /// An instance of a Mutex object that contains a 71 /// valid mutex object. 72 //-------------------------------------------------------------- 73 Locker(Mutex& m); 74 75 //-------------------------------------------------------------- 76 /// Constructor with a Mutex object pointer. 77 /// 78 /// This will create a scoped mutex locking object that extracts 79 /// the mutex owned by a m and locks it. 80 /// 81 /// @param[in] m 82 /// A pointer to instance of a Mutex object that 83 /// contains a valid mutex object. 84 //-------------------------------------------------------------- 85 Locker(Mutex* m); 86 87 //-------------------------------------------------------------- 88 /// Desstructor 89 /// 90 /// Unlocks any valid pthread_mutex_t that this object may 91 /// contain. 92 //-------------------------------------------------------------- 93 ~Locker(); 94 95 //-------------------------------------------------------------- 96 /// Change the contained mutex. 97 /// 98 /// Unlock the current mutex in this object (if it contains a 99 /// valid mutex) and lock the new \a mutex object if it is 100 /// non-NULL. 101 //-------------------------------------------------------------- 102 void 103 Lock (Mutex &mutex); 104 105 void Lock(Mutex * mutex)106 Lock (Mutex *mutex) 107 { 108 if (mutex) 109 Lock(*mutex); 110 } 111 112 //-------------------------------------------------------------- 113 /// Change the contained mutex only if the mutex can be locked. 114 /// 115 /// Unlock the current mutex in this object (if it contains a 116 /// valid mutex) and try to lock \a mutex. If \a mutex can be 117 /// locked this object will take ownership of the lock and will 118 /// unlock it when it goes out of scope or Reset or TryLock are 119 /// called again. If the mutex is already locked, this object 120 /// will not take ownership of the mutex. 121 /// 122 /// @return 123 /// Returns \b true if the lock was aquired and the this 124 /// object will unlock the mutex when it goes out of scope, 125 /// returns \b false otherwise. 126 //-------------------------------------------------------------- 127 bool 128 TryLock (Mutex &mutex, const char *failure_message = NULL); 129 130 bool 131 TryLock (Mutex *mutex, const char *failure_message = NULL) 132 { 133 if (mutex) 134 return TryLock(*mutex, failure_message); 135 else 136 return false; 137 } 138 139 void 140 Unlock (); 141 142 protected: 143 //-------------------------------------------------------------- 144 /// Member variables 145 //-------------------------------------------------------------- 146 Mutex *m_mutex_ptr; 147 148 private: 149 Locker(const Locker&); 150 const Locker& operator=(const Locker&); 151 }; 152 153 154 //------------------------------------------------------------------ 155 /// Default constructor. 156 /// 157 /// Creates a pthread mutex with no attributes. 158 //------------------------------------------------------------------ 159 Mutex(); 160 161 //------------------------------------------------------------------ 162 /// Default constructor. 163 /// 164 /// Creates a pthread mutex with \a type as the mutex type. 165 /// Valid values for \a type include: 166 /// @li Mutex::Type::eMutexTypeNormal 167 /// @li Mutex::Type::eMutexTypeRecursive 168 /// 169 /// @param[in] type 170 /// The type of the mutex. 171 /// 172 /// @see ::pthread_mutexattr_settype() 173 //------------------------------------------------------------------ 174 Mutex(Mutex::Type type); 175 176 //------------------------------------------------------------------ 177 /// Destructor. 178 /// 179 /// Destroys the mutex owned by this object. 180 //------------------------------------------------------------------ 181 #ifdef LLDB_CONFIGURATION_DEBUG 182 virtual 183 #endif 184 ~Mutex(); 185 186 //------------------------------------------------------------------ 187 /// Lock the mutex. 188 /// 189 /// Locks the mutex owned by this object. If the mutex is already 190 /// locked, the calling thread will block until the mutex becomes 191 /// available. 192 /// 193 /// @return 194 /// The error code from \c pthread_mutex_lock(). 195 //------------------------------------------------------------------ 196 #ifdef LLDB_CONFIGURATION_DEBUG 197 virtual 198 #endif 199 int 200 Lock(); 201 202 //------------------------------------------------------------------ 203 /// Try to lock the mutex. 204 /// 205 /// Attempts to lock the mutex owned by this object without blocking. 206 /// If the mutex is already locked, TryLock() will not block waiting 207 /// for the mutex, but will return an error condition. 208 /// 209 /// @return 210 /// The error code from \c pthread_mutex_trylock(). 211 //------------------------------------------------------------------ 212 #ifdef LLDB_CONFIGURATION_DEBUG 213 virtual 214 #endif 215 int 216 TryLock(const char *failure_message = NULL); 217 218 //------------------------------------------------------------------ 219 /// Unlock the mutex. 220 /// 221 /// If the current thread holds the lock on the owned mutex, then 222 /// Unlock() will unlock the mutex. Calling Unlock() on this object 223 /// when the calling thread does not hold the lock will result in 224 /// undefined behavior. 225 /// 226 /// @return 227 /// The error code from \c pthread_mutex_unlock(). 228 //------------------------------------------------------------------ 229 #ifdef LLDB_CONFIGURATION_DEBUG 230 virtual 231 #endif 232 int 233 Unlock(); 234 235 protected: 236 //------------------------------------------------------------------ 237 // Member variables 238 //------------------------------------------------------------------ 239 // TODO: Hide the mutex in the implementation file in case we ever need to port to an 240 // architecture that doesn't have pthread mutexes. 241 pthread_mutex_t m_mutex; ///< The pthread mutex object. 242 243 private: 244 //------------------------------------------------------------------ 245 /// Mutex get accessor. 246 /// 247 /// @return 248 /// A pointer to the pthread mutex object owned by this object. 249 //------------------------------------------------------------------ 250 pthread_mutex_t * 251 GetMutex(); 252 253 Mutex(const Mutex&); 254 const Mutex& operator=(const Mutex&); 255 }; 256 257 #ifdef LLDB_CONFIGURATION_DEBUG 258 class TrackingMutex : public Mutex 259 { 260 public: TrackingMutex()261 TrackingMutex() : Mutex() {} TrackingMutex(Mutex::Type type)262 TrackingMutex(Mutex::Type type) : Mutex (type) {} 263 264 virtual ~TrackingMutex()265 ~TrackingMutex() {} 266 267 virtual int 268 Unlock (); 269 270 virtual int 271 TryLock (const char *failure_message = NULL) 272 { 273 int return_value = Mutex::TryLock(); 274 if (return_value != 0 && failure_message != NULL) 275 { 276 m_failure_message.assign(failure_message); 277 m_thread_that_tried = pthread_self(); 278 } 279 return return_value; 280 } 281 282 protected: 283 pthread_t m_thread_that_tried; 284 std::string m_failure_message; 285 }; 286 287 class LoggingMutex : public Mutex 288 { 289 public: LoggingMutex()290 LoggingMutex() : Mutex(),m_locked(false) {} LoggingMutex(Mutex::Type type)291 LoggingMutex(Mutex::Type type) : Mutex (type),m_locked(false) {} 292 293 virtual ~LoggingMutex()294 ~LoggingMutex() {} 295 296 virtual int 297 Lock (); 298 299 virtual int 300 Unlock (); 301 302 virtual int 303 TryLock (const char *failure_message = NULL); 304 protected: 305 bool m_locked; 306 }; 307 #endif 308 309 } // namespace lldb_private 310 311 #endif // #if defined(__cplusplus) 312 #endif 313