Barrier.h

Go to the documentation of this file.
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