Fixed two major bugs in paxos.cc.
[invirt/third/libt4.git] / rpc / fifo.h
1 #ifndef fifo_h
2 #define fifo_h
3
4 #include "types.h"
5
6 // blocks enq() and deq() when queue is FULL or EMPTY
7 template<class T>
8 class fifo {
9     public:
10         fifo(size_t limit=0) : max_(limit) {}
11         bool enq(T, bool blocking=true);
12         void deq(T *);
13         bool size() {
14             lock ml(m_);
15             return q_.size();
16         }
17
18     private:
19         list<T> q_;
20         mutex m_;
21         cond non_empty_c_; // q went non-empty
22         cond has_space_c_; // q is not longer overfull
23         size_t max_; // maximum capacity of the queue, block enq threads if exceeds this limit
24 };
25
26 template<class T> bool
27 fifo<T>::enq(T e, bool blocking)
28 {
29     lock ml(m_);
30     while (max_ && q_.size() >= max_) {
31         if (!blocking)
32             return false;
33         has_space_c_.wait(ml);
34     }
35     q_.push_back(e);
36     non_empty_c_.notify_one();
37     return true;
38 }
39
40 template<class T> void
41 fifo<T>::deq(T *e)
42 {
43     lock ml(m_);
44     while(q_.empty())
45         non_empty_c_.wait(ml);
46     *e = q_.front();
47     q_.pop_front();
48     if (max_ && q_.size() < max_)
49         has_space_c_.notify_one();
50 }
51
52 #endif