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 //---------------------------------------------------------------------- 23 namespace 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 32 class ProcessRunLock 33 { 34 public: ProcessRunLock()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 ~ProcessRunLock()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 ReadTryLock()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 ReadUnlock()66 ReadUnlock () 67 { 68 return ::pthread_rwlock_unlock (&m_rwlock) == 0; 69 } 70 71 bool SetRunning()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 TrySetRunning()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 SetStopped()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: ProcessRunLocker()107 ProcessRunLocker () : 108 m_lock (NULL) 109 { 110 } 111 ~ProcessRunLocker()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 TryLock(ProcessRunLock * lock)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 Unlock()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 155 protected: 156 pthread_rwlock_t m_rwlock; 157 bool m_running; 158 private: 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