threadsafe_queue.h 2.4 KB

#ifndef __THREADSAFE_QUEUE_H__
#define __THREADSAFE_QUEUE_H__

#include <queue>
#include <mutex>
#include <condition_variable>
#include <initializer_list>

#include <pthread.h>
using std::queue;
using namespace std;

template <typename T>
class ThreadedQueue : public queue<T> {
public:
    ThreadedQueue();
    ~ThreadedQueue();
    bool empty() const;
    size_t size() const;
    void push(const T& val);
    void push(T& val);
    bool pop();
    T& front();
    const T& front() const;
    T& back();
    const T& back() const;

    void Put(T &data);

    T Take();
    void Get(T &data);
    bool GetEmpty();

    condition_variable *condition;
    mutex *lock;
};

template <typename T>
ThreadedQueue<T>::ThreadedQueue() {
    lock = new mutex;
    condition = new condition_variable;
}

template <typename T>
ThreadedQueue<T>::~ThreadedQueue() {
    if(condition != nullptr){
        delete condition;
        condition = nullptr;
    }
    if(lock != nullptr){
        delete lock;
        lock = nullptr;
    }
}

template <typename T>
T ThreadedQueue<T>:: Take()
{
    std::unique_lock<std::mutex> lk(this->lock);
    this->condition->wait(lk, [this]{return !this->empty();});
    T val = this->front();
    this->pop();
    return val;
}

template <typename T>
void ThreadedQueue<T>:: Put(T &data)
{
  std::unique_lock<std::mutex> lk(*lock);
  this->push(data);
  this->condition->notify_one();
  return;
}

template <typename T>
void ThreadedQueue<T>:: Get(T &data)
{
    std::unique_lock<std::mutex> lk(*lock);
    this->condition->wait(lk, [this]{return !this->empty();});
    data = this->front();
    this->pop();
}

template <typename T>
bool ThreadedQueue<T>::GetEmpty()
{
    std::unique_lock<std::mutex> lk(*lock);
    this->condition->wait(lk, [this]{return !this->empty();});
    return true;
}


template <typename T>
bool ThreadedQueue<T>::empty() const {
    bool result = queue<T>::empty();
    return result;
}

template <typename T>
size_t ThreadedQueue<T>::size() const {
    size_t result = queue<T>::size();
    return result;
}

template <typename T>
void ThreadedQueue<T>::push(T& val) {
    queue<T>::push(val);
}


template <typename T>
T& ThreadedQueue<T>::front() {
    T& result = queue<T>::front();
    return result;
}

template <typename T>
bool ThreadedQueue<T>::pop() {
    bool result = false;
    if(!queue<T>::empty()) {
        queue<T>::pop();
        result = true;
    }
    return result;
}

#endif