#ifndef __CONCURRENCEQUEUE_H__
#define __CONCURRENCEQUEUE_H__
#include <mutex>
#include <condition_variable>
#include <deque>
#include <queue>
#include <memory>
template<typename DATATYPE, typename SEQUENCE = std::deque<DATATYPE>>
class ConcurrenceQueue {
public:
ConcurrenceQueue() = default;
~ConcurrenceQueue() = default;
ConcurrenceQueue & operator= (const ConcurrenceQueue &) = delete;
bool empty() const {
std::lock_guard<std::mutex> lg(m_mutex);
return m_data.empty();
}
int size(){
std::lock_guard<std::mutex>lg(m_mutex);
return m_data.size();
}
int push(const DATATYPE & data) {
std::lock_guard<std::mutex> lg(m_mutex);
if(m_data.size()>maxSize)
return 0;
m_data.push(data);
m_cond.notify_one();
return m_data.size();
}
std::shared_ptr<DATATYPE> tryPop() {
std::lock_guard<std::mutex> lg(m_mutex);
if (m_data.empty()) return {};
auto res = std::make_shared<DATATYPE>(m_data.front());
m_data.pop();
return res;
}
std::shared_ptr<DATATYPE> pop() {
std::unique_lock<std::mutex> lg(m_mutex);
m_cond.wait(lg, [this] { return !m_data.empty(); });
auto res = std::make_shared<DATATYPE>(std::move(m_data.front()));
m_data.pop();
return res;
}
std::shared_ptr<DATATYPE> pop(int sec) {
std::unique_lock<std::mutex> lg(m_mutex);
bool notempty = m_cond.wait_for(lg, std::chrono::seconds(sec),[this] { return !m_data.empty(); });
if(!notempty)
return {};
auto res = std::make_shared<DATATYPE>(std::move(m_data.front()));
m_data.pop();
return res;
}
private:
int maxSize=10;
std::queue<DATATYPE, SEQUENCE> m_data;
mutable std::mutex m_mutex;
std::condition_variable m_cond;
};
#endif
|