Mutex.h revision 516f0849819d094d4eab39a1f27b770259103ff8
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
17namespace lldb_private {
18
19//----------------------------------------------------------------------
20/// @class Mutex Mutex.h "lldb/Host/Mutex.h"
21/// @brief A C++ wrapper class for pthread mutexes.
22//----------------------------------------------------------------------
23class Mutex
24{
25public:
26    enum Type
27    {
28        eMutexTypeNormal,       ///< Mutex that can't recursively entered by the same thread
29        eMutexTypeRecursive     ///< Mutex can be recursively entered by the same thread
30    };
31
32    //------------------------------------------------------------------
33    /// @class Mutex::Locker
34    ///
35    /// A scoped locking class that allows a variety of pthread mutex
36    /// objects to have a mutex locked when an Mutex::Locker
37    /// object is created, and unlocked when it goes out of scope or
38    /// when the Mutex::Locker::Reset(pthread_mutex_t *)
39    /// is called. This provides an exception safe way to lock a mutex
40    /// in a scope.
41    //------------------------------------------------------------------
42    class Locker
43    {
44    public:
45        //--------------------------------------------------------------
46        /// Default constructor.
47        ///
48        /// This will create a scoped mutex locking object that doesn't
49        /// have a mutex to lock. One will need to be provided using the
50        /// Mutex::Locker::Reset(pthread_mutex_t *) method.
51        ///
52        /// @see Mutex::Locker::Reset(pthread_mutex_t *)
53        //--------------------------------------------------------------
54        Locker();
55
56        //--------------------------------------------------------------
57        /// Constructor with a Mutex object.
58        ///
59        /// This will create a scoped mutex locking object that extracts
60        /// the mutex owned by \a m and locks it.
61        ///
62        /// @param[in] m
63        ///     An instance of a Mutex object that contains a
64        ///     valid mutex object.
65        //--------------------------------------------------------------
66        Locker(Mutex& m);
67
68        //--------------------------------------------------------------
69        /// Constructor with a Mutex object pointer.
70        ///
71        /// This will create a scoped mutex locking object that extracts
72        /// the mutex owned by a m and locks it.
73        ///
74        /// @param[in] m
75        ///     A pointer to instance of a Mutex object that
76        ///     contains a valid mutex object.
77        //--------------------------------------------------------------
78        Locker(Mutex* m);
79
80        //--------------------------------------------------------------
81        /// Constructor with a raw pthread mutex object pointer.
82        ///
83        /// This will create a scoped mutex locking object that locks
84        /// \a mutex.
85        ///
86        /// @param[in] mutex
87        ///     A pointer to a pthread_mutex_t that will get locked if
88        ///     non-NULL.
89        //--------------------------------------------------------------
90        Locker(pthread_mutex_t *mutex);
91
92        //--------------------------------------------------------------
93        /// Desstructor
94        ///
95        /// Unlocks any valid pthread_mutex_t that this object may
96        /// contain.
97        //--------------------------------------------------------------
98        ~Locker();
99
100        //--------------------------------------------------------------
101        /// Change the contained mutex.
102        ///
103        /// Unlock the current mutex in this object (if it contains a
104        /// valid mutex) and lock the new \a mutex object if it is
105        /// non-NULL.
106        //--------------------------------------------------------------
107        void
108        Lock (pthread_mutex_t *mutex);
109
110        //--------------------------------------------------------------
111        /// Change the contained mutex only if the mutex can be locked.
112        ///
113        /// Unlock the current mutex in this object (if it contains a
114        /// valid mutex) and try to lock \a mutex. If \a mutex can be
115        /// locked this object will take ownership of the lock and will
116        /// unlock it when it goes out of scope or Reset or TryLock are
117        /// called again. If the mutex is already locked, this object
118        /// will not take ownership of the mutex.
119        ///
120        /// @return
121        ///     Returns \b true if the lock was aquired and the this
122        ///     object will unlock the mutex when it goes out of scope,
123        ///     returns \b false otherwise.
124        //--------------------------------------------------------------
125        bool
126        TryLock (pthread_mutex_t *mutex);
127
128        void
129        Unlock ();
130
131    protected:
132        //--------------------------------------------------------------
133        /// Member variables
134        //--------------------------------------------------------------
135        pthread_mutex_t *m_mutex_ptr;   ///< A pthread mutex that is locked when
136                                        ///< acquired and unlocked when destroyed
137                                        ///< or reset.
138
139    private:
140        Locker(const Locker&);
141        const Locker& operator=(const Locker&);
142    };
143
144
145    //------------------------------------------------------------------
146    /// Default constructor.
147    ///
148    /// Creates a pthread mutex with no attributes.
149    //------------------------------------------------------------------
150    Mutex();
151
152    //------------------------------------------------------------------
153    /// Default constructor.
154    ///
155    /// Creates a pthread mutex with \a type as the mutex type.
156    /// Valid values for \a type include:
157    ///     @li Mutex::Type::eMutexTypeNormal
158    ///     @li Mutex::Type::eMutexTypeRecursive
159    ///
160    /// @param[in] type
161    ///     The type of the mutex.
162    ///
163    /// @see ::pthread_mutexattr_settype()
164    //------------------------------------------------------------------
165    Mutex(Mutex::Type type);
166
167    //------------------------------------------------------------------
168    /// Destructor.
169    ///
170    /// Destroys the mutex owned by this object.
171    //------------------------------------------------------------------
172    ~Mutex();
173
174    //------------------------------------------------------------------
175    /// Mutex get accessor.
176    ///
177    /// @return
178    ///     A pointer to the pthread mutex object owned by this object.
179    //------------------------------------------------------------------
180    pthread_mutex_t *
181    GetMutex();
182
183    //------------------------------------------------------------------
184    /// Lock the mutex.
185    ///
186    /// Locks the mutex owned by this object. If the mutex is already
187    /// locked, the calling thread will block until the mutex becomes
188    /// available.
189    ///
190    /// @return
191    ///     The error code from \c pthread_mutex_lock().
192    //------------------------------------------------------------------
193    int
194    Lock();
195
196    //------------------------------------------------------------------
197    /// Try to lock the mutex.
198    ///
199    /// Attempts to lock the mutex owned by this object without blocking.
200    /// If the mutex is already locked, TryLock() will not block waiting
201    /// for the mutex, but will return an error condition.
202    ///
203    /// @return
204    ///     The error code from \c pthread_mutex_trylock().
205    //------------------------------------------------------------------
206    int
207    TryLock();
208
209    //------------------------------------------------------------------
210    /// Unlock the mutex.
211    ///
212    /// If the current thread holds the lock on the owned mutex, then
213    /// Unlock() will unlock the mutex. Calling Unlock() on this object
214    /// when the calling thread does not hold the lock will result in
215    /// undefined behavior.
216    ///
217    /// @return
218    ///     The error code from \c pthread_mutex_unlock().
219    //------------------------------------------------------------------
220    int
221    Unlock();
222
223    static
224    int Lock (pthread_mutex_t *mutex_ptr);
225
226    static
227    int TryLock (pthread_mutex_t *mutex_ptr);
228
229    static
230    int Unlock (pthread_mutex_t *mutex_ptr);
231
232protected:
233    //------------------------------------------------------------------
234    // Member variables
235    //------------------------------------------------------------------
236    pthread_mutex_t m_mutex; ///< The pthread mutex object.
237private:
238    Mutex(const Mutex&);
239    const Mutex& operator=(const Mutex&);
240};
241
242} // namespace lldb_private
243
244#endif  // #if defined(__cplusplus)
245#endif
246