Home | History | Annotate | Download | only in Host
      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:
     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 
    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