aboutsummaryrefslogtreecommitdiff
path: root/include/lldb/Host/Mutex.h
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2013-08-23 17:46:38 +0000
committerEd Maste <emaste@FreeBSD.org>2013-08-23 17:46:38 +0000
commitf034231a6a1fd5d6395206c1651de8cd9402cca3 (patch)
treef561dabc721ad515599172c16da3a4400b7f4aec /include/lldb/Host/Mutex.h
downloadsrc-f034231a6a1fd5d6395206c1651de8cd9402cca3.tar.gz
src-f034231a6a1fd5d6395206c1651de8cd9402cca3.zip
Import lldb as of SVN r188801
(A number of files not required for the FreeBSD build have been removed.) Sponsored by: DARPA, AFRL
Notes
Notes: svn path=/vendor/lldb/dist/; revision=254721
Diffstat (limited to 'include/lldb/Host/Mutex.h')
-rw-r--r--include/lldb/Host/Mutex.h312
1 files changed, 312 insertions, 0 deletions
diff --git a/include/lldb/Host/Mutex.h b/include/lldb/Host/Mutex.h
new file mode 100644
index 000000000000..63f759efe366
--- /dev/null
+++ b/include/lldb/Host/Mutex.h
@@ -0,0 +1,312 @@
+//===-- Mutex.h -------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Mutex_h_
+#define liblldb_Mutex_h_
+#if defined(__cplusplus)
+
+#include <pthread.h>
+#include <assert.h>
+
+#ifdef LLDB_CONFIGURATION_DEBUG
+#include <string>
+#endif
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Mutex Mutex.h "lldb/Host/Mutex.h"
+/// @brief A C++ wrapper class for pthread mutexes.
+//----------------------------------------------------------------------
+class Mutex
+{
+public:
+ friend class Locker;
+ friend class Condition;
+
+ enum Type
+ {
+ eMutexTypeNormal, ///< Mutex that can't recursively entered by the same thread
+ eMutexTypeRecursive ///< Mutex can be recursively entered by the same thread
+ };
+
+ //------------------------------------------------------------------
+ /// @class Mutex::Locker
+ ///
+ /// A scoped locking class that allows a variety of pthread mutex
+ /// objects to have a mutex locked when an Mutex::Locker
+ /// object is created, and unlocked when it goes out of scope or
+ /// when the Mutex::Locker::Reset(pthread_mutex_t *)
+ /// is called. This provides an exception safe way to lock a mutex
+ /// in a scope.
+ //------------------------------------------------------------------
+ class Locker
+ {
+ public:
+ //--------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// This will create a scoped mutex locking object that doesn't
+ /// have a mutex to lock. One will need to be provided using the
+ /// Mutex::Locker::Reset(pthread_mutex_t *) method.
+ ///
+ /// @see Mutex::Locker::Reset(pthread_mutex_t *)
+ //--------------------------------------------------------------
+ Locker();
+
+ //--------------------------------------------------------------
+ /// Constructor with a Mutex object.
+ ///
+ /// This will create a scoped mutex locking object that extracts
+ /// the mutex owned by \a m and locks it.
+ ///
+ /// @param[in] m
+ /// An instance of a Mutex object that contains a
+ /// valid mutex object.
+ //--------------------------------------------------------------
+ Locker(Mutex& m);
+
+ //--------------------------------------------------------------
+ /// Constructor with a Mutex object pointer.
+ ///
+ /// This will create a scoped mutex locking object that extracts
+ /// the mutex owned by a m and locks it.
+ ///
+ /// @param[in] m
+ /// A pointer to instance of a Mutex object that
+ /// contains a valid mutex object.
+ //--------------------------------------------------------------
+ Locker(Mutex* m);
+
+ //--------------------------------------------------------------
+ /// Desstructor
+ ///
+ /// Unlocks any valid pthread_mutex_t that this object may
+ /// contain.
+ //--------------------------------------------------------------
+ ~Locker();
+
+ //--------------------------------------------------------------
+ /// Change the contained mutex.
+ ///
+ /// Unlock the current mutex in this object (if it contains a
+ /// valid mutex) and lock the new \a mutex object if it is
+ /// non-NULL.
+ //--------------------------------------------------------------
+ void
+ Lock (Mutex &mutex);
+
+ void
+ Lock (Mutex *mutex)
+ {
+ if (mutex)
+ Lock(*mutex);
+ }
+
+ //--------------------------------------------------------------
+ /// Change the contained mutex only if the mutex can be locked.
+ ///
+ /// Unlock the current mutex in this object (if it contains a
+ /// valid mutex) and try to lock \a mutex. If \a mutex can be
+ /// locked this object will take ownership of the lock and will
+ /// unlock it when it goes out of scope or Reset or TryLock are
+ /// called again. If the mutex is already locked, this object
+ /// will not take ownership of the mutex.
+ ///
+ /// @return
+ /// Returns \b true if the lock was aquired and the this
+ /// object will unlock the mutex when it goes out of scope,
+ /// returns \b false otherwise.
+ //--------------------------------------------------------------
+ bool
+ TryLock (Mutex &mutex, const char *failure_message = NULL);
+
+ bool
+ TryLock (Mutex *mutex, const char *failure_message = NULL)
+ {
+ if (mutex)
+ return TryLock(*mutex, failure_message);
+ else
+ return false;
+ }
+
+ void
+ Unlock ();
+
+ protected:
+ //--------------------------------------------------------------
+ /// Member variables
+ //--------------------------------------------------------------
+ Mutex *m_mutex_ptr;
+
+ private:
+ Locker(const Locker&);
+ const Locker& operator=(const Locker&);
+ };
+
+
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Creates a pthread mutex with no attributes.
+ //------------------------------------------------------------------
+ Mutex();
+
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Creates a pthread mutex with \a type as the mutex type.
+ /// Valid values for \a type include:
+ /// @li Mutex::Type::eMutexTypeNormal
+ /// @li Mutex::Type::eMutexTypeRecursive
+ ///
+ /// @param[in] type
+ /// The type of the mutex.
+ ///
+ /// @see ::pthread_mutexattr_settype()
+ //------------------------------------------------------------------
+ Mutex(Mutex::Type type);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// Destroys the mutex owned by this object.
+ //------------------------------------------------------------------
+#ifdef LLDB_CONFIGURATION_DEBUG
+ virtual
+#endif
+ ~Mutex();
+
+ //------------------------------------------------------------------
+ /// Lock the mutex.
+ ///
+ /// Locks the mutex owned by this object. If the mutex is already
+ /// locked, the calling thread will block until the mutex becomes
+ /// available.
+ ///
+ /// @return
+ /// The error code from \c pthread_mutex_lock().
+ //------------------------------------------------------------------
+#ifdef LLDB_CONFIGURATION_DEBUG
+ virtual
+#endif
+ int
+ Lock();
+
+ //------------------------------------------------------------------
+ /// Try to lock the mutex.
+ ///
+ /// Attempts to lock the mutex owned by this object without blocking.
+ /// If the mutex is already locked, TryLock() will not block waiting
+ /// for the mutex, but will return an error condition.
+ ///
+ /// @return
+ /// The error code from \c pthread_mutex_trylock().
+ //------------------------------------------------------------------
+#ifdef LLDB_CONFIGURATION_DEBUG
+ virtual
+#endif
+ int
+ TryLock(const char *failure_message = NULL);
+
+ //------------------------------------------------------------------
+ /// Unlock the mutex.
+ ///
+ /// If the current thread holds the lock on the owned mutex, then
+ /// Unlock() will unlock the mutex. Calling Unlock() on this object
+ /// when the calling thread does not hold the lock will result in
+ /// undefined behavior.
+ ///
+ /// @return
+ /// The error code from \c pthread_mutex_unlock().
+ //------------------------------------------------------------------
+#ifdef LLDB_CONFIGURATION_DEBUG
+ virtual
+#endif
+ int
+ Unlock();
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ // TODO: Hide the mutex in the implementation file in case we ever need to port to an
+ // architecture that doesn't have pthread mutexes.
+ pthread_mutex_t m_mutex; ///< The pthread mutex object.
+
+private:
+ //------------------------------------------------------------------
+ /// Mutex get accessor.
+ ///
+ /// @return
+ /// A pointer to the pthread mutex object owned by this object.
+ //------------------------------------------------------------------
+ pthread_mutex_t *
+ GetMutex();
+
+ Mutex(const Mutex&);
+ const Mutex& operator=(const Mutex&);
+};
+
+#ifdef LLDB_CONFIGURATION_DEBUG
+class TrackingMutex : public Mutex
+{
+public:
+ TrackingMutex() : Mutex() {}
+ TrackingMutex(Mutex::Type type) : Mutex (type) {}
+
+ virtual
+ ~TrackingMutex() {}
+
+ virtual int
+ Unlock ();
+
+ virtual int
+ TryLock (const char *failure_message = NULL)
+ {
+ int return_value = Mutex::TryLock();
+ if (return_value != 0 && failure_message != NULL)
+ {
+ m_failure_message.assign(failure_message);
+ m_thread_that_tried = pthread_self();
+ }
+ return return_value;
+ }
+
+protected:
+ pthread_t m_thread_that_tried;
+ std::string m_failure_message;
+};
+
+class LoggingMutex : public Mutex
+{
+public:
+ LoggingMutex() : Mutex(),m_locked(false) {}
+ LoggingMutex(Mutex::Type type) : Mutex (type),m_locked(false) {}
+
+ virtual
+ ~LoggingMutex() {}
+
+ virtual int
+ Lock ();
+
+ virtual int
+ Unlock ();
+
+ virtual int
+ TryLock (const char *failure_message = NULL);
+protected:
+ bool m_locked;
+};
+#endif
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif