ThreadSafeQueue.h 1.52 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
#pragma once

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

namespace ROSBridge {

template <class T>
class ThreadSafeQueue
{
public:
    ThreadSafeQueue();
    ~ThreadSafeQueue();

    T pop_front();

    void push_back(const T& item);
    void push_back(T&& item);

    int size();
    bool empty();

private:
    std::deque<T> _queue;
    std::mutex _mutex;
    std::condition_variable _cond;
};

template <typename T>
ThreadSafeQueue<T>::ThreadSafeQueue(){}

template <typename T>
ThreadSafeQueue<T>::~ThreadSafeQueue(){}

template <typename T>
T ThreadSafeQueue<T>::pop_front()
{
    std::unique_lock<std::mutex> mlock(_mutex);
    while (_queue.empty())
    {
        _cond.wait(mlock);
    }
    T t = std::move(_queue.front());
    _queue.pop_front();
    return t;
}

template <typename T>
void ThreadSafeQueue<T>::push_back(const T& item)
{
    std::unique_lock<std::mutex> mlock(_mutex);
    _queue.push_back(item);
    mlock.unlock();     // unlock before notificiation to minimize mutex con
    _cond.notify_one(); // notify one waiting thread

}

template <typename T>
void ThreadSafeQueue<T>::push_back(T&& item)
{
    std::unique_lock<std::mutex> mlock(_mutex);
    _queue.push_back(std::move(item));
    mlock.unlock();     // unlock before notificiation to minimize mutex con
    _cond.notify_one(); // notify one waiting thread

}

template <typename T>
int ThreadSafeQueue<T>::size()
{
    std::unique_lock<std::mutex> mlock(_mutex);
    int size = _queue.size();
    mlock.unlock();
    return size;
}

} // namespace