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