root/software/photo_compress_archiver/ProtectedAndSynchronizedQueue.h @ 26cc955b
| fea928c1 | David Sorber | #ifndef __PROTECTEDANDSYNCHRONIZEDQUEUE_H__
|
||
#define __PROTECTEDANDSYNCHRONIZEDQUEUE_H__
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <iostream>
|
||||
template<class T>
|
||||
class ProtectedAndSynchronizedQueue
|
||||
{
|
||||
public:
|
||||
ProtectedAndSynchronizedQueue()
|
||||
{
|
||||
m_terminateFlag = false;
|
||||
}
|
||||
virtual ~ProtectedAndSynchronizedQueue() {};
|
||||
| 4f6113f8 | David Sorber | // add a new element to the back of the queue
|
||
| fea928c1 | David Sorber | void push_back(T newElement)
|
||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
m_queue.push(newElement);
|
||||
}
|
||||
m_CV.notify_one();
|
||||
}
|
||||
| 4f6113f8 | David Sorber | // retrieve the first element of the queue and remove it
|
||
// from the queue
|
||||
| fea928c1 | David Sorber | T pop_front()
|
||
{
|
||||
// Wait on queue blocking
|
||||
std::unique_lock<std::mutex> muxLock(m_mutex);
|
||||
while (m_queue.empty())
|
||||
{
|
||||
m_CV.wait(muxLock);
|
||||
// If we've been asked to terminate, break out and return
|
||||
// NOTE: the return value is garbage if terminate has been
|
||||
// called prior this call returning
|
||||
if (m_terminateFlag)
|
||||
{
|
||||
T elementToReturn;
|
||||
return elementToReturn;
|
||||
}
|
||||
}
|
||||
T elementToReturn = m_queue.front();
|
||||
m_queue.pop();
|
||||
muxLock.unlock();
|
||||
return elementToReturn;
|
||||
}
|
||||
| 4f6113f8 | David Sorber | // retrieve the first element of the queue and remove it
|
||
// from the queue
|
||||
| fea928c1 | David Sorber | T pop_front(bool waitOnEmptyQueue, bool& elementReturned)
|
||
{
|
||||
// Wait on queue blocking
|
||||
std::unique_lock<std::mutex> muxLock(m_mutex);
|
||||
if (waitOnEmptyQueue)
|
||||
{
|
||||
while (m_queue.empty())
|
||||
{
|
||||
m_CV.wait(muxLock);
|
||||
// If we've been asked to terminate, break out and return
|
||||
// NOTE: the return value is garbage if terminate has been
|
||||
// called prior this call returning
|
||||
if (m_terminateFlag)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
T elementToReturn;
|
||||
if (m_queue.size() > 0)
|
||||
{
|
||||
elementReturned = true;
|
||||
elementToReturn = m_queue.front();
|
||||
m_queue.pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
elementReturned = false;
|
||||
}
|
||||
| 4f6113f8 | David Sorber | muxLock.unlock();
|
||
| fea928c1 | David Sorber | |||
return elementToReturn;
|
||||
}
|
||||
| 4f6113f8 | David Sorber | // terminate any waiting pop_front() requests
|
||
| fea928c1 | David Sorber | void terminate()
|
||
{
|
||||
m_terminateFlag = true;
|
||||
m_CV.notify_all();
|
||||
}
|
||||
bool empty()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
return m_queue.empty();
|
||||
}
|
||||
| 4f6113f8 | David Sorber | uint32_t size()
|
||
| fea928c1 | David Sorber | {
|
||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
return m_queue.size();
|
||||
}
|
||||
private:
|
||||
bool m_terminateFlag;
|
||||
std::queue<T> m_queue;
|
||||
std::mutex m_mutex;
|
||||
std::condition_variable m_CV;
|
||||
};
|
||||
| 4f6113f8 | David Sorber | #endif
|