#ifndef __COARSE__QUEUE__H__
#define __COARSE__QUEUE__H__
#ifdef _MSC_VER
#if _MSC_VER > 1000
#pragma once
#endif
#endif
#include <queue>
#include <mutex>
#include <memory>
#include <condition_variable>
namespace stc{
template <typename type>
class coarse_queue{
typedef std::shared_ptr<type> shared_ptr;
typedef std::queue<shared_ptr> queue;
typedef coarse_queue <type> self;
public:
coarse_queue() = default;
coarse_queue(const self&) = delete;
self& operator =(const self&) = delete;
void wait_and_pop(type&);
bool try_pop(type&);
shared_ptr wait_and_pop();
shared_ptr try_pop();
void push(type);
bool empty()const;
private:
queue m_queue;
mutable std::mutex m_mutex;
std::condition_variable m_cv;
};
template <typename type>
void coarse_queue<type>::wait_and_pop(type& value){
std::unique_lock<std::mutex> lock(m_mutex);
m_cv.wait(lock, [this] { return !m_queue.empty(); });
value = std::move(*(m_queue.front()));
m_queue.pop();
}
template <typename type>
bool coarse_queue<type>::try_pop(type& value){
std::lock_guard<std::mutex> lock(m_mutex);
if (m_queue.empty()) return (false);//if the queue is empty then return false to the caller
value = std::move(*(m_queue.front()));
m_queue.pop();
return (true);
}
template <typename type>
typename coarse_queue<type>::shared_ptr
coarse_queue<type>::wait_and_pop(){
std::unique_lock<std::mutex> lock(m_mutex);
m_cv.wait(lock, [this] {return !m_queue.empty(); });
shared_ptr res = m_queue.front();
m_queue.pop();
return (res);
}
template <typename type>
typename coarse_queue<type>::shared_ptr
coarse_queue<type>::try_pop(){
std::lock_guard<std::mutex> lock(m_mutex);
if (m_queue.empty()) return false;
shared_ptr res = m_queue.front();
m_queue.pop();
return (res);
}
template <typename type>
void coarse_queue<type>::push(type value){
std::shared_ptr<type> item(std::make_shared<type>(value));
std::lock_guard<std::mutex> lock(m_mutex);
m_queue.push(item);
m_cv.notify_one();
}
template <typename type>
bool coarse_queue<type>::empty()const{
std::lock_guard<std::mutex> lock(m_mutex);
return (m_queue.empty());
}
}
#endif
#ifndef __FINE__QUEUE__H__
#define __FINE__QUEUE__H__
#ifdef _MSC_VER
#if _MSC_VER > 1000
#pragma once
#endif
#endif
#include <memory>
#include <mutex>
#include <condition_variable>
namespace stc{
template <typename type>
struct list_node{
std::unique_ptr<type> m_next;
std::shared_ptr<type> m_data;
list_node() :m_next(NULL){}
};
template <typename type>
class fine_queue{
typedef fine_queue<type> self;
typedef std::shared_ptr<type> shared_ptr;
typedef list_node<type> list_node;
public:
fine_queue();
fine_queue(const self&) = delete;
self& operator =(const self&) = delete;
public:
void push(type);
bool empty()const;
bool try_pop(type&);
std::shared_ptr<type> try_pop();
std::shared_ptr<type> wait_and_pop();
void wait_and_pop(type&);
private:
list_node* get_tail();
std::unique_ptr<list_node> pop_head();
std::unique_lock<std::mutex> wait_for_data();
std::unique_ptr<list_node> wait_pop_head();
std::unique_ptr<list_node> wait_pop_head(type&);
std::unique_ptr<list_node> try_pop_head();
std::unique_ptr<list_node> try_pop_head(type&);
private:
list_node* m_tail;
mutable std::mutex m_head_mutex;
mutable std::mutex m_tail_mutex;
std::unique_ptr<list_node> m_head;
std::condition_variable m_cv;
};
template <typename type>
fine_queue<type>::fine_queue()
:m_head(new list_node){
m_tail = m_head.get();
}
template <typename type>
void fine_queue<type>::push(type value){
shared_ptr item(std::make_shared<type>(value));
std::unique_ptr<list_node> node(new list_node);
{
std::lock_guard<std::mutex> lock(m_tail_mutex);
m_tail->m_data = item;
list_node* next = node.get();
m_tail->m_next = std::move(node);
m_tail = next;
}
m_cv.notify_one();
}
template <typename type>
typename fine_queue<type>::list_node*
fine_queue<type>::get_tail(){
std::lock_guard<std::mutex> lock(m_tail);
return (m_tail);
}
template <typename type>
std::unique_ptr<list_node<type> >
fine_queue<type>::pop_head(){
std::unique_ptr<list_node> o_node = std::move(m_head);
m_head = o_node->m_next;
return (o_node);
}
template <typename type>
std::unique_lock<std::mutex> fine_queue<type>::wait_for_data(){
std::unique_lock<std::mutex> lock(m_head_mutex);
m_cv.wait(lock, [this] { return this->m_head.get() != get_tail(); });
return (std::move(lock));
}
template <typename type>
std::unique_ptr<list_node<type> > fine_queue<type>::wait_pop_head(){
std::unique_lock<std::mutex> lock(wait_for_data());
return (pop_head());
}
template <typename type>
std::unique_ptr<list_node<type> > fine_queue<type>::wait_pop_head(type& value){
std::unique_lock<std::mutex> lock(wait_for_data);
value = std::move(*m_head);
return (pop_head());
}
template <typename type>
std::shared_ptr<type> fine_queue<type>::wait_and_pop(){
std::unique_ptr<list_node> res = this->wait_pop_head();
return (res->m_data);
}
template <typename type>
void fine_queue<type>::wait_and_pop(type& value){
wait_pop_head(value);
}
template <typename type>
std::unique_ptr<list_node<type> > fine_queue<type>::try_pop_head(){
std::lock_guard<std::mutex> lock(m_head_mutex);
if (m_head.get() == get_tail())
return (std::unique_ptr<list_node>());
return (pop_head());
}
template <typename type>
std::unique_ptr<list_node<type> > fine_queue<type>::try_pop_head(type& value){
std::lock_guard<std::mutex> lock(m_head_mutex);
if (m_head.get() == get_tail())
return (std::unique_ptr<list_node>());
value = std::move(*m_head);
return (pop_head());
}
template <typename type>
std::shared_ptr<type> fine_queue<type>::try_pop(){
std::unique_ptr<list_node> res = try_pop_head();
return res ? (res->m_data) : (std::shared_ptr<type>());
}
template <typename type>
bool fine_queue<type>::try_pop(type& value){
const std::unique_ptr<list_node> res = try_pop_head(value);
return (res);
}
template <typename type>
bool fine_queue<type>::empty()const{
std::lock_guard<std::mutex> lock(m_head_mutex);
return (m_head.get() == get_tail());
}
}
#endif