00001 00022 #ifndef HYPERTABLE_BARRIER_H 00023 #define HYPERTABLE_BARRIER_H 00024 00025 #include <boost/thread/condition.hpp> 00026 #include <boost/thread/mutex.hpp> 00027 00028 #include "Mutex.h" 00029 00030 namespace Hypertable { 00031 00032 class Barrier { 00033 public: 00034 00035 Barrier() : m_hold(false), m_counter(0) { 00036 } 00037 00040 void enter() { 00041 ScopedLock lock(m_mutex); 00042 while (m_hold) 00043 m_unblocked_cond.wait(lock); 00044 m_counter++; 00045 } 00046 00049 void exit() { 00050 ScopedLock lock(m_mutex); 00051 m_counter--; 00052 if (m_hold && m_counter == 0) 00053 m_quiesced_cond.notify_one(); 00054 } 00055 00058 void put_up() { 00059 ScopedLock lock(m_mutex); 00060 m_hold = true; 00061 while (m_counter > 0) 00062 m_quiesced_cond.wait(lock); 00063 } 00064 00067 void take_down() { 00068 ScopedLock lock(m_mutex); 00069 m_hold = false; 00070 m_unblocked_cond.notify_all(); 00071 } 00072 00073 class ScopedActivator { 00074 public: 00075 ScopedActivator(Barrier &barrier) : m_barrier(barrier) { 00076 m_barrier.put_up(); 00077 } 00078 ~ScopedActivator() { 00079 m_barrier.take_down(); 00080 } 00081 private: 00082 Barrier &m_barrier; 00083 }; 00084 00085 private: 00086 Mutex m_mutex; 00087 boost::condition m_unblocked_cond; 00088 boost::condition m_quiesced_cond; 00089 bool m_hold; 00090 uint32_t m_counter; 00091 00092 }; 00093 00094 } 00095 00096 #endif // HYPERTABLE_BARRIER_H
1.7.2