124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- Mutex.h -------------------------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifndef liblldb_Mutex_h_
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#define liblldb_Mutex_h_
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#if defined(__cplusplus)
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <pthread.h>
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <assert.h>
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham#ifdef LLDB_CONFIGURATION_DEBUG
18088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham#include <string>
19088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham#endif
20088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnernamespace lldb_private {
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/// @class Mutex Mutex.h "lldb/Host/Mutex.h"
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/// @brief A C++ wrapper class for pthread mutexes.
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass Mutex
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic:
301b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham    friend class Locker;
311b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham    friend class Condition;
321b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    enum Type
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        eMutexTypeNormal,       ///< Mutex that can't recursively entered by the same thread
36e28824e0b988221c7eedf8e3d212527d2bdac6a7Eli Friedman        eMutexTypeRecursive     ///< Mutex can be recursively entered by the same thread
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    };
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// @class Mutex::Locker
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ///
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// A scoped locking class that allows a variety of pthread mutex
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// objects to have a mutex locked when an Mutex::Locker
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// object is created, and unlocked when it goes out of scope or
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// when the Mutex::Locker::Reset(pthread_mutex_t *)
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// is called. This provides an exception safe way to lock a mutex
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// in a scope.
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    class Locker
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    public:
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        //--------------------------------------------------------------
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// Default constructor.
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ///
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// This will create a scoped mutex locking object that doesn't
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// have a mutex to lock. One will need to be provided using the
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// Mutex::Locker::Reset(pthread_mutex_t *) method.
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ///
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// @see Mutex::Locker::Reset(pthread_mutex_t *)
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        //--------------------------------------------------------------
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Locker();
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        //--------------------------------------------------------------
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// Constructor with a Mutex object.
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ///
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// This will create a scoped mutex locking object that extracts
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// the mutex owned by \a m and locks it.
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ///
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// @param[in] m
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ///     An instance of a Mutex object that contains a
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ///     valid mutex object.
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        //--------------------------------------------------------------
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Locker(Mutex& m);
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        //--------------------------------------------------------------
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// Constructor with a Mutex object pointer.
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ///
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// This will create a scoped mutex locking object that extracts
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// the mutex owned by a m and locks it.
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ///
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// @param[in] m
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ///     A pointer to instance of a Mutex object that
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ///     contains a valid mutex object.
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        //--------------------------------------------------------------
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Locker(Mutex* m);
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        //--------------------------------------------------------------
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// Desstructor
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ///
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// Unlocks any valid pthread_mutex_t that this object may
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// contain.
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        //--------------------------------------------------------------
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ~Locker();
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        //--------------------------------------------------------------
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// Change the contained mutex.
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ///
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// Unlock the current mutex in this object (if it contains a
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// valid mutex) and lock the new \a mutex object if it is
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// non-NULL.
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        //--------------------------------------------------------------
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        void
1031b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham        Lock (Mutex &mutex);
1041b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham
1051b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham        void
1061b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham        Lock (Mutex *mutex)
1071b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham        {
1081b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham            if (mutex)
1091b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham                Lock(*mutex);
1101b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham        }
11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        //--------------------------------------------------------------
11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// Change the contained mutex only if the mutex can be locked.
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ///
11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// Unlock the current mutex in this object (if it contains a
11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// valid mutex) and try to lock \a mutex. If \a mutex can be
11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// locked this object will take ownership of the lock and will
11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// unlock it when it goes out of scope or Reset or TryLock are
11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// called again. If the mutex is already locked, this object
12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// will not take ownership of the mutex.
12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ///
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// @return
12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ///     Returns \b true if the lock was aquired and the this
12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ///     object will unlock the mutex when it goes out of scope,
12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ///     returns \b false otherwise.
12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        //--------------------------------------------------------------
12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        bool
128088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham        TryLock (Mutex &mutex, const char *failure_message = NULL);
1291b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham
1301b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham        bool
131088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham        TryLock (Mutex *mutex, const char *failure_message = NULL)
1321b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham        {
1331b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham            if (mutex)
134088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham                return TryLock(*mutex, failure_message);
1351b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham            else
1361b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham                return false;
1371b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham        }
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
139516f0849819d094d4eab39a1f27b770259103ff8Greg Clayton        void
140516f0849819d094d4eab39a1f27b770259103ff8Greg Clayton        Unlock ();
141516f0849819d094d4eab39a1f27b770259103ff8Greg Clayton
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    protected:
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        //--------------------------------------------------------------
14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /// Member variables
14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        //--------------------------------------------------------------
146088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham        Mutex *m_mutex_ptr;
14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    private:
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Locker(const Locker&);
15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const Locker& operator=(const Locker&);
15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    };
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// Default constructor.
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ///
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// Creates a pthread mutex with no attributes.
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Mutex();
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// Default constructor.
16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ///
16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// Creates a pthread mutex with \a type as the mutex type.
16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// Valid values for \a type include:
16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ///     @li Mutex::Type::eMutexTypeNormal
16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ///     @li Mutex::Type::eMutexTypeRecursive
16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ///
16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// @param[in] type
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ///     The type of the mutex.
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ///
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// @see ::pthread_mutexattr_settype()
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Mutex(Mutex::Type type);
17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// Destructor.
17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ///
17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// Destroys the mutex owned by this object.
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
181088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham#ifdef LLDB_CONFIGURATION_DEBUG
182088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham    virtual
183088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham#endif
18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ~Mutex();
18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// Lock the mutex.
18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ///
18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// Locks the mutex owned by this object. If the mutex is already
19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// locked, the calling thread will block until the mutex becomes
19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// available.
19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ///
19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// @return
19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ///     The error code from \c pthread_mutex_lock().
19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
196559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata#ifdef LLDB_CONFIGURATION_DEBUG
197559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata    virtual
198559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata#endif
19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int
20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Lock();
20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// Try to lock the mutex.
20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ///
20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// Attempts to lock the mutex owned by this object without blocking.
20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// If the mutex is already locked, TryLock() will not block waiting
20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// for the mutex, but will return an error condition.
20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ///
20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// @return
21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ///     The error code from \c pthread_mutex_trylock().
21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
212088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham#ifdef LLDB_CONFIGURATION_DEBUG
213088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham    virtual
214088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham#endif
21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int
216088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham    TryLock(const char *failure_message = NULL);
21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// Unlock the mutex.
22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ///
22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// If the current thread holds the lock on the owned mutex, then
22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// Unlock() will unlock the mutex. Calling Unlock() on this object
22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// when the calling thread does not hold the lock will result in
22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// undefined behavior.
22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ///
22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// @return
22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ///     The error code from \c pthread_mutex_unlock().
22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
229088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham#ifdef LLDB_CONFIGURATION_DEBUG
230088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham    virtual
231088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham#endif
23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int
23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Unlock();
23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprotected:
23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Member variables
23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //------------------------------------------------------------------
239088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham    // TODO: Hide the mutex in the implementation file in case we ever need to port to an
240088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham    // architecture that doesn't have pthread mutexes.
24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    pthread_mutex_t m_mutex; ///< The pthread mutex object.
2421b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham
24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprivate:
2441b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham    //------------------------------------------------------------------
2451b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham    /// Mutex get accessor.
2461b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham    ///
2471b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham    /// @return
2481b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham    ///     A pointer to the pthread mutex object owned by this object.
2491b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham    //------------------------------------------------------------------
2501b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham    pthread_mutex_t *
2511b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham    GetMutex();
2521b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham
25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Mutex(const Mutex&);
25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const Mutex& operator=(const Mutex&);
25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner};
25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
257088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham#ifdef LLDB_CONFIGURATION_DEBUG
258088684d31c66df959fa2f3840f00b73b79b07756Jim Inghamclass TrackingMutex : public Mutex
259088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham{
260088684d31c66df959fa2f3840f00b73b79b07756Jim Inghampublic:
261088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham    TrackingMutex() : Mutex()  {}
262088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham    TrackingMutex(Mutex::Type type) : Mutex (type) {}
263088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham
264088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham    virtual
265088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham    ~TrackingMutex() {}
266088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham
267088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham    virtual int
268088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham    Unlock ();
269088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham
270088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham    virtual int
271088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham    TryLock (const char *failure_message = NULL)
272088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham    {
273088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham        int return_value = Mutex::TryLock();
274088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham        if (return_value != 0 && failure_message != NULL)
275088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham        {
276088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham            m_failure_message.assign(failure_message);
277088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham            m_thread_that_tried = pthread_self();
278088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham        }
279088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham        return return_value;
280088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham    }
281088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham
282088684d31c66df959fa2f3840f00b73b79b07756Jim Inghamprotected:
283088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham    pthread_t m_thread_that_tried;
284088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham    std::string m_failure_message;
285088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham};
286559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata
287559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granataclass LoggingMutex : public Mutex
288559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata{
289559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granatapublic:
290559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata    LoggingMutex() : Mutex(),m_locked(false)  {}
291559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata    LoggingMutex(Mutex::Type type) : Mutex (type),m_locked(false) {}
292559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata
293559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata    virtual
294559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata    ~LoggingMutex() {}
295559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata
296559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata    virtual int
297559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata    Lock ();
298559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata
299559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata    virtual int
300559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata    Unlock ();
301559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata
302559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata    virtual int
303559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata    TryLock (const char *failure_message = NULL);
304559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granataprotected:
305559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata    bool m_locked;
306559bb5cacf6777cf1ad8ee32256585d049123332Enrico Granata};
307088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham#endif
308088684d31c66df959fa2f3840f00b73b79b07756Jim Ingham
30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} // namespace lldb_private
31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif  // #if defined(__cplusplus)
31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif
313