ProcessRunLock.h revision cf88b95d435873bd312e716da5701cf3882c5da4
1//===-- ProcessRunLock.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_ProcessRunLock_h_
11#define liblldb_ProcessRunLock_h_
12#if defined(__cplusplus)
13
14#include "lldb/Host/Mutex.h"
15#include "lldb/Host/Condition.h"
16#include <pthread.h>
17#include <stdint.h>
18#include <time.h>
19
20//----------------------------------------------------------------------
21/// Enumerations for broadcasting.
22//----------------------------------------------------------------------
23namespace lldb_private {
24
25//----------------------------------------------------------------------
26/// @class ProcessRunLock ProcessRunLock.h "lldb/Host/ProcessRunLock.h"
27/// @brief A class used to prevent the process from starting while other
28/// threads are accessing its data, and prevent access to its data while
29/// it is running.
30//----------------------------------------------------------------------
31
32class ProcessRunLock
33{
34public:
35    ProcessRunLock () :
36        m_rwlock(),
37        m_running(false)
38    {
39        int err = ::pthread_rwlock_init(&m_rwlock, NULL); (void)err;
40//#if LLDB_CONFIGURATION_DEBUG
41//        assert(err == 0);
42//#endif
43    }
44
45    ~ProcessRunLock ()
46    {
47        int err = ::pthread_rwlock_destroy (&m_rwlock); (void)err;
48//#if LLDB_CONFIGURATION_DEBUG
49//        assert(err == 0);
50//#endif
51    }
52
53    bool
54    ReadTryLock ()
55    {
56        ::pthread_rwlock_rdlock (&m_rwlock);
57        if (m_running == false)
58        {
59            return true;
60        }
61        ::pthread_rwlock_unlock (&m_rwlock);
62        return false;
63    }
64
65    bool
66    ReadUnlock ()
67    {
68        return ::pthread_rwlock_unlock (&m_rwlock) == 0;
69    }
70
71    bool
72    SetRunning()
73    {
74        ::pthread_rwlock_wrlock (&m_rwlock);
75        m_running = true;
76        ::pthread_rwlock_unlock (&m_rwlock);
77        return true;
78    }
79
80    bool
81    TrySetRunning()
82    {
83        bool r;
84
85        if (::pthread_rwlock_trywrlock (&m_rwlock) == 0)
86        {
87            r = !m_running;
88            m_running = true;
89            ::pthread_rwlock_unlock (&m_rwlock);
90            return r;
91        }
92        return false;
93    }
94
95    bool
96    SetStopped ()
97    {
98        ::pthread_rwlock_wrlock (&m_rwlock);
99        m_running = false;
100        ::pthread_rwlock_unlock (&m_rwlock);
101        return true;
102    }
103
104    class ProcessRunLocker
105    {
106    public:
107        ProcessRunLocker () :
108            m_lock (NULL)
109        {
110        }
111
112        ~ProcessRunLocker()
113        {
114            Unlock();
115        }
116
117        // Try to lock the read lock, but only do so if there are no writers.
118        bool
119        TryLock (ProcessRunLock *lock)
120        {
121            if (m_lock)
122            {
123                if (m_lock == lock)
124                    return true; // We already have this lock locked
125                else
126                    Unlock();
127            }
128            if (lock)
129            {
130                if (lock->ReadTryLock())
131                {
132                    m_lock = lock;
133                    return true;
134                }
135            }
136            return false;
137        }
138
139    protected:
140        void
141        Unlock ()
142        {
143            if (m_lock)
144            {
145                m_lock->ReadUnlock();
146                m_lock = NULL;
147            }
148        }
149
150        ProcessRunLock *m_lock;
151    private:
152        DISALLOW_COPY_AND_ASSIGN(ProcessRunLocker);
153    };
154
155protected:
156    pthread_rwlock_t m_rwlock;
157    bool m_running;
158private:
159    DISALLOW_COPY_AND_ASSIGN(ProcessRunLock);
160};
161
162} // namespace lldb_private
163
164#endif  // #if defined(__cplusplus)
165#endif // #ifndef liblldb_ProcessRunLock_h_
166