#ifndef UDPC_THREADSAFE_QUEUE_HPP #define UDPC_THREADSAFE_QUEUE_HPP #define UDPC_TSQUEUE_DEFAULT_CAPACITY 32 #include #include #include #include template class TSQueue { public: TSQueue(unsigned int capacity = UDPC_TSQUEUE_DEFAULT_CAPACITY); ~TSQueue(); // disable copy TSQueue(const TSQueue &other) = delete; TSQueue &operator=(const TSQueue &other) = delete; // disable move TSQueue(TSQueue &&other) = delete; TSQueue &operator=(TSQueue &&other) = delete; bool push(const T &data); T top(); bool pop(); void clear(); void changeCapacity(unsigned int newCapacity); unsigned int size(); bool empty(); private: std::mutex mutex; RB::RingBuffer rb; }; template TSQueue::TSQueue(unsigned int capacity) : mutex(), rb(capacity) { rb.setResizePolicy(false); } template TSQueue::~TSQueue() {} template bool TSQueue::push(const T &data) { std::lock_guard lock(mutex); if(rb.getSize() == rb.getCapacity()) { return false; } rb.push(data); return true; } template T TSQueue::top() { std::lock_guard lock(mutex); T value = rb.top(); return value; } template bool TSQueue::pop() { std::lock_guard lock(mutex); if(rb.empty()) { return false; } rb.pop(); return true; } template void TSQueue::clear() { std::lock_guard lock(mutex); rb.resize(0); } template void TSQueue::changeCapacity(unsigned int newCapacity) { std::lock_guard lock(mutex); rb.changeCapacity(newCapacity); } template unsigned int TSQueue::size() { std::lock_guard lock(mutex); unsigned int size = rb.getSize(); return size; } template bool TSQueue::empty() { // No lock required, since this is calling size() that uses a lock unsigned int size = this->size(); return size == 0; } #endif