dfb4d059d4625235da0ae6302aed3d253c60fd87
[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
12         bool enq(T e, bool blocking=true) {
13             lock ml(m_);
14             while (max_ && q_.size() >= max_) {
15                 if (!blocking)
16                     return false;
17                 has_space_c_.wait(ml);
18             }
19             q_.push_back(e);
20             non_empty_c_.notify_one();
21             return true;
22         }
23
24         void deq(T * e) {
25             lock ml(m_);
26             while(q_.empty())
27                 non_empty_c_.wait(ml);
28             *e = q_.front();
29             q_.pop_front();
30             if (max_ && q_.size() < max_)
31                 has_space_c_.notify_one();
32         }
33
34         bool size() {
35             lock ml(m_);
36             return q_.size();
37         }
38
39     private:
40         std::list<T> q_;
41         std::mutex m_;
42         cond non_empty_c_; // q went non-empty
43         cond has_space_c_; // q is not longer overfull
44         size_t max_; // maximum capacity of the queue, block enq threads if exceeds this limit
45 };
46
47 #endif