blob: f361ad7f471ba69c9b153f9516a20ef7c2fb540e [file] [log] [blame]
//===-- 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>
namespace lldb_private {
//----------------------------------------------------------------------
/// @class Mutex Mutex.h "lldb/Host/Mutex.h"
/// @brief A C++ wrapper class for pthread mutexes.
//----------------------------------------------------------------------
class Mutex
{
public:
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);
//--------------------------------------------------------------
/// Constructor with a raw pthread mutex object pointer.
///
/// This will create a scoped mutex locking object that locks
/// \a mutex.
///
/// @param[in] mutex
/// A pointer to a pthread_mutex_t that will get locked if
/// non-NULL.
//--------------------------------------------------------------
Locker(pthread_mutex_t *mutex);
//--------------------------------------------------------------
/// 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 (pthread_mutex_t *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 (pthread_mutex_t *mutex);
void
Unlock ();
protected:
//--------------------------------------------------------------
/// Member variables
//--------------------------------------------------------------
pthread_mutex_t *m_mutex_ptr; ///< A pthread mutex that is locked when
///< acquired and unlocked when destroyed
///< or reset.
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.
//------------------------------------------------------------------
~Mutex();
//------------------------------------------------------------------
/// Mutex get accessor.
///
/// @return
/// A pointer to the pthread mutex object owned by this object.
//------------------------------------------------------------------
pthread_mutex_t *
GetMutex();
//------------------------------------------------------------------
/// 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().
//------------------------------------------------------------------
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().
//------------------------------------------------------------------
int
TryLock();
//------------------------------------------------------------------
/// 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().
//------------------------------------------------------------------
int
Unlock();
static
int Lock (pthread_mutex_t *mutex_ptr);
static
int TryLock (pthread_mutex_t *mutex_ptr);
static
int Unlock (pthread_mutex_t *mutex_ptr);
protected:
//------------------------------------------------------------------
// Member variables
//------------------------------------------------------------------
pthread_mutex_t m_mutex; ///< The pthread mutex object.
private:
Mutex(const Mutex&);
const Mutex& operator=(const Mutex&);
};
} // namespace lldb_private
#endif // #if defined(__cplusplus)
#endif