Project

General

Profile

Download (3.22 KB) Statistics
| Branch: | Tag: | Revision:
#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() {};
// add a new element to the back of the queue
void push_back(T newElement)
{
{
std::lock_guard<std::mutex> lock(m_mutex);
m_queue.push(newElement);
}
m_CV.notify_one();
}
// retrieve the first element of the queue and remove it
// from the queue
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;
}

// retrieve the first element of the queue and remove it
// from the queue
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;
}
muxLock.unlock();

return elementToReturn;
}
// terminate any waiting pop_front() requests
void terminate()
{
m_terminateFlag = true;
m_CV.notify_all();
}
bool empty()
{
std::lock_guard<std::mutex> lock(m_mutex);
return m_queue.empty();
}
uint32_t size()
{
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;
};

#endif
(6-6/7)