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