Major clean-ups. Migrating to C++11.
[invirt/third/libt4.git] / rpc / fifo.h
1 #ifndef fifo_h
2 #define fifo_h
3
4 // fifo template
5 // blocks enq() and deq() when queue is FULL or EMPTY
6
7 #include <errno.h>
8 #include <list>
9 #include <sys/time.h>
10 #include <time.h>
11 #include <errno.h>
12 #include "lang/verify.h"
13 #include "lock.h"
14
15 template<class T>
16 class fifo {
17         public:
18                 fifo(int m=0);
19                 bool enq(T, bool blocking=true);
20                 void deq(T *);
21                 bool size();
22
23         private:
24                 std::list<T> q_;
25         mutex m_;
26         std::condition_variable non_empty_c_; // q went non-empty
27                 std::condition_variable has_space_c_; // q is not longer overfull
28                 unsigned int max_; //maximum capacity of the queue, block enq threads if exceeds this limit
29 };
30
31 template<class T>
32 fifo<T>::fifo(int limit) : max_(limit)
33 {
34 }
35
36 template<class T> bool
37 fifo<T>::size()
38 {
39     lock ml(m_);
40         return q_.size();
41 }
42
43 template<class T> bool
44 fifo<T>::enq(T e, bool blocking)
45 {
46     lock ml(m_);
47         while (1) {
48                 if (!max_ || q_.size() < max_) {
49                         q_.push_back(e);
50                         break;
51                 }
52                 if (blocking) {
53             has_space_c_.wait(ml);
54         }
55                 else
56                         return false;
57         }
58     non_empty_c_.notify_one();
59         return true;
60 }
61
62 template<class T> void
63 fifo<T>::deq(T *e)
64 {
65         lock ml(m_);
66
67         while(1) {
68                 if(q_.empty()){
69             non_empty_c_.wait(ml);
70                 } else {
71                         *e = q_.front();
72                         q_.pop_front();
73                         if (max_ && q_.size() < max_) {
74                 has_space_c_.notify_one();
75                         }
76                         break;
77                 }
78         }
79         return;
80 }
81
82 #endif