CuteLogger
Fast and simple logging solution for Qt based applications
dataqueue.h
1 /*
2  * Copyright (c) 2015 Meltytech, LLC
3  * Author: Brian Matherly <code@brianmatherly.com>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef DATAQUEUE_H
20 #define DATAQUEUE_H
21 
22 #include <QMutex>
23 #include <QMutexLocker>
24 #include <QWaitCondition>
25 
26 #include <deque>
27 
47 template<class T>
48 class DataQueue
49 {
50 public:
52  typedef enum {
57 
64  explicit DataQueue(int maxSize, OverflowMode mode);
65 
67  virtual ~DataQueue();
68 
75  void push(const T &item);
76 
83  T pop();
84 
86  int count() const;
87 
88 private:
89  std::deque<T> m_queue;
90  int m_maxSize;
91  OverflowMode m_mode;
92  mutable QMutex m_mutex;
93  QWaitCondition m_notEmptyCondition;
94  QWaitCondition m_notFullCondition;
95 };
96 
97 template<class T>
99  : m_queue()
100  , m_maxSize(maxSize)
101  , m_mode(mode)
102  , m_mutex()
103  , m_notEmptyCondition()
104  , m_notFullCondition()
105 {}
106 
107 template<class T>
109 {}
110 
111 template<class T>
112 void DataQueue<T>::push(const T &item)
113 {
114  m_mutex.lock();
115  if (m_queue.size() == m_maxSize) {
116  switch (m_mode) {
117  case OverflowModeDiscardOldest:
118  m_queue.pop_front();
119  m_queue.push_back(item);
120  break;
121  case OverflowModeDiscardNewest:
122  // This item is the newest so discard it and exit
123  break;
124  case OverflowModeWait:
125  m_notFullCondition.wait(&m_mutex);
126  m_queue.push_back(item);
127  break;
128  }
129  } else {
130  m_queue.push_back(item);
131  if (m_queue.size() == 1) {
132  m_notEmptyCondition.wakeOne();
133  }
134  }
135  m_mutex.unlock();
136 }
137 
138 template<class T>
140 {
141  T retVal;
142  m_mutex.lock();
143  if (m_queue.size() == 0) {
144  m_notEmptyCondition.wait(&m_mutex);
145  }
146  retVal = m_queue.front();
147  m_queue.pop_front();
148  if (m_mode == OverflowModeWait && m_queue.size() == m_maxSize - 1) {
149  m_notFullCondition.wakeOne();
150  }
151  m_mutex.unlock();
152  return retVal;
153 }
154 
155 template<class T>
157 {
158  QMutexLocker locker(&m_mutex);
159  return m_queue.size();
160 }
161 
162 #endif // DATAQUEUE_H
The DataQueue provides a thread safe container for passing data between objects.
Definition: dataqueue.h:49
OverflowMode
Overflow behavior modes.
Definition: dataqueue.h:52
@ OverflowModeWait
Wait for space to be free.
Definition: dataqueue.h:55
@ OverflowModeDiscardNewest
Discard newest items.
Definition: dataqueue.h:54
@ OverflowModeDiscardOldest
Discard oldest items.
Definition: dataqueue.h:53
DataQueue(int maxSize, OverflowMode mode)
Definition: dataqueue.h:98
T pop()
Definition: dataqueue.h:139
int count() const
Returns the number of items in the queue.
Definition: dataqueue.h:156
virtual ~DataQueue()
Destructs a DataQueue.
Definition: dataqueue.h:108
void push(const T &item)
Definition: dataqueue.h:112