]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/debugserver/source/PThreadMutex.h
Vendor import of lldb trunk r290819:
[FreeBSD/FreeBSD.git] / tools / debugserver / source / PThreadMutex.h
1 //===-- PThreadMutex.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 //  Created by Greg Clayton on 6/16/07.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef __PThreadMutex_h__
15 #define __PThreadMutex_h__
16
17 #include <assert.h>
18 #include <pthread.h>
19 #include <stdint.h>
20
21 //#define DEBUG_PTHREAD_MUTEX_DEADLOCKS 1
22
23 #if defined(DEBUG_PTHREAD_MUTEX_DEADLOCKS)
24 #define PTHREAD_MUTEX_LOCKER(var, mutex)                                       \
25   PThreadMutex::Locker var(mutex, __FUNCTION__, __FILE__, __LINE__)
26
27 #else
28 #define PTHREAD_MUTEX_LOCKER(var, mutex) PThreadMutex::Locker var(mutex)
29 #endif
30
31 class PThreadMutex {
32 public:
33   class Locker {
34   public:
35 #if defined(DEBUG_PTHREAD_MUTEX_DEADLOCKS)
36
37     Locker(PThreadMutex &m, const char *function, const char *file, int line);
38     Locker(PThreadMutex *m, const char *function, const char *file, int line);
39     Locker(pthread_mutex_t *mutex, const char *function, const char *file,
40            int line);
41     ~Locker();
42     void Lock();
43     void Unlock();
44
45 #else
46     Locker(PThreadMutex &m) : m_pMutex(m.Mutex()) { Lock(); }
47
48     Locker(PThreadMutex *m) : m_pMutex(m ? m->Mutex() : NULL) { Lock(); }
49
50     Locker(pthread_mutex_t *mutex) : m_pMutex(mutex) { Lock(); }
51
52     void Lock() {
53       if (m_pMutex)
54         ::pthread_mutex_lock(m_pMutex);
55     }
56
57     void Unlock() {
58       if (m_pMutex)
59         ::pthread_mutex_unlock(m_pMutex);
60     }
61
62     ~Locker() { Unlock(); }
63
64 #endif
65
66     // unlock any the current mutex and lock the new one if it is valid
67     void Reset(pthread_mutex_t *pMutex = NULL) {
68       Unlock();
69       m_pMutex = pMutex;
70       Lock();
71     }
72     pthread_mutex_t *m_pMutex;
73 #if defined(DEBUG_PTHREAD_MUTEX_DEADLOCKS)
74     const char *m_function;
75     const char *m_file;
76     int m_line;
77     uint64_t m_lock_time;
78 #endif
79   };
80
81   PThreadMutex() {
82     int err;
83     err = ::pthread_mutex_init(&m_mutex, NULL);
84     assert(err == 0);
85   }
86
87   PThreadMutex(int type) {
88     int err;
89     ::pthread_mutexattr_t attr;
90     err = ::pthread_mutexattr_init(&attr);
91     assert(err == 0);
92     err = ::pthread_mutexattr_settype(&attr, type);
93     assert(err == 0);
94     err = ::pthread_mutex_init(&m_mutex, &attr);
95     assert(err == 0);
96     err = ::pthread_mutexattr_destroy(&attr);
97     assert(err == 0);
98   }
99
100   ~PThreadMutex() {
101     int err;
102     err = ::pthread_mutex_destroy(&m_mutex);
103     if (err != 0) {
104       err = Unlock();
105       if (err == 0)
106         ::pthread_mutex_destroy(&m_mutex);
107     }
108   }
109
110   pthread_mutex_t *Mutex() { return &m_mutex; }
111
112   int Lock() { return ::pthread_mutex_lock(&m_mutex); }
113
114   int Unlock() { return ::pthread_mutex_unlock(&m_mutex); }
115
116 protected:
117   pthread_mutex_t m_mutex;
118 };
119
120 #endif