FACT++  1.0
queue.h
Go to the documentation of this file.
1 #ifndef FACT_Queue
2 #define FACT_Queue
3 
4 #include <list>
5 #include <thread>
6 #include <condition_variable>
7 
8 template<class T>
9 class Queue
10 {
11  size_t fSize; // Only necessary for before C++11
12 
13  std::list<T> fList;
14 
15  std::mutex fMutex; // Mutex needed for the conditional
16  std::condition_variable fCond; // Conditional
17 
18  enum state_t
19  {
20  kIdle,
21  kRun,
22  kStop,
23  kAbort,
24  };
25 
26  state_t fState; // Stop signal for the thread
27 
28  typedef std::function<void(const T &)> callback;
29  callback fCallback; // Callback function called by the thread
30 
31  std::thread fThread; // Handle to the thread
32 
33  void Thread()
34  {
35  std::unique_lock<std::mutex> lock(fMutex);
36 
37  while (1)
38  {
39  while (fList.empty() && fState==kRun)
40  fCond.wait(lock);
41 
42  if (fState==kAbort)
43  break;
44 
45  if (fState==kStop && fList.empty())
46  break;
47 
48  const T &val = fList.front();
49 
50  // Theoretically, we can loose a signal here, but this is
51  // not a problem, because then we detect a non-empty queue
52  lock.unlock();
53 
54  if (fCallback)
55  fCallback(val);
56 
57  lock.lock();
58 
59  fList.pop_front();
60  fSize--;
61  }
62 
63  fList.clear();
64  fSize = 0;
65 
66  fState = kIdle;
67  }
68 
69 public:
70  Queue(const callback &f) : fSize(0), fState(kIdle), fCallback(f)
71  {
72  start();
73  }
75  {
76  wait(true);
77  }
78 
79  bool start()
80  {
81  const std::lock_guard<std::mutex> lock(fMutex);
82  if (fState!=kIdle)
83  return false;
84 
85  fState = kRun;
86  fThread = std::thread(std::bind(&Queue::Thread, this));
87  return true;
88  }
89 
90  bool stop()
91  {
92  const std::lock_guard<std::mutex> lock(fMutex);
93  if (fState==kIdle)
94  return false;
95 
96  fState = kStop;
97  fCond.notify_one();
98 
99  return true;
100  }
101 
102  bool abort()
103  {
104  const std::lock_guard<std::mutex> lock(fMutex);
105  if (fState==kIdle)
106  return false;
107 
108  fState = kAbort;
109  fCond.notify_one();
110 
111  return true;
112  }
113 
114  bool wait(bool abrt=false)
115  {
116  {
117  const std::lock_guard<std::mutex> lock(fMutex);
118  if (fState==kIdle)
119  return false;
120 
121  if (fState==kRun)
122  {
123  fState = abrt ? kAbort : kStop;
124  fCond.notify_one();
125  }
126  }
127 
128  fThread.join();
129  return true;
130  }
131 
132  bool post(const T &val)
133  {
134  const std::lock_guard<std::mutex> lock(fMutex);
135  if (fState==kIdle)
136  return false;
137 
138  fList.push_back(val);
139  fSize++;
140 
141  fCond.notify_one();
142 
143  return true;
144  }
145 
146 #ifdef __GXX_EXPERIMENTAL_CXX0X__
147  template<typename... _Args>
148  bool emplace(_Args&&... __args)
149  {
150  const std::lock_guard<std::mutex> lock(fMutex);
151  if (fState==kIdle)
152  return false;
153 
154  fList.emplace_back(__args...);
155  fSize++;
156 
157  fCond.notify_one();
158 
159  return true;
160  }
161 
162  bool post(T &&val) { return emplace(std::move(val)); }
163 #endif
164 
165 #ifdef __GXX_EXPERIMENTAL_CXX0X__
166  bool move(std::list<T>&& x, typename std::list<T>::iterator i)
167 #else
168  bool move(std::list<T>& x, typename std::list<T>::iterator i)
169 #endif
170  {
171  const std::lock_guard<std::mutex> lock(fMutex);
172  if (fState==kIdle)
173  return false;
174 
175  fList.splice(fList.end(), x, i);
176  fSize++;
177 
178  fCond.notify_one();
179 
180  return true;
181  }
182 
183 #ifdef __GXX_EXPERIMENTAL_CXX0X__
184  bool move(std::list<T>& x, typename std::list<T>::iterator i) { return move(std::move(x), i); }
185 #endif
186 
187  size_t size() const
188  {
189  return fSize;
190  }
191 
192  bool empty() const
193  {
194  return fSize==0;
195  }
196 };
197 
198 #endif
bool abort()
Definition: queue.h:102
state_t fState
Definition: Queue.h:48
int i
Definition: db_dim_client.c:21
bool start()
Definition: Queue.h:151
Definition: Queue.h:28
callback fCallback
Definition: Queue.h:51
bool move(std::list< T > &x, typename std::list< T >::iterator i)
Definition: queue.h:168
std::condition_variable fCond
Definition: Queue.h:35
bool wait(bool abrt=false)
Definition: Queue.h:186
std::mutex fMutex
Definition: Queue.h:34
bool empty() const
Definition: queue.h:192
std::thread fThread
Definition: Queue.h:53
bool stop()
Definition: queue.h:90
bool post(const T &val)
Definition: queue.h:132
void Thread()
Definition: queue.h:33
std::list< T > fList
Definition: queue.h:13
size_t size() const
Definition: queue.h:187
std::function< void(const T &)> callback
Definition: queue.h:28
bool move(List &x, typename List::iterator i)
Definition: Queue.h:284
Queue(const callback &f)
Definition: queue.h:70
size_t fSize
Definition: Queue.h:30
~Queue()
Definition: queue.h:74