/*** A thread safe queue. * From: http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html * Author: Anthony Williams */ #ifndef __TQUEUE_H__ #define __TQUEUE_H__ #include #include #include #include template < class T, class Container = std::vector, class Compare = std::less > class pqueue : public std::priority_queue { public: const T& front() const { return std::priority_queue::top(); } }; template< typename Data, class Container = std::queue > class concurrent_queue { private: Container the_queue; mutable boost::mutex the_mutex; boost::condition cond_not_empty; boost::condition cond_not_full; public: void push(Data const& data) { boost::mutex::scoped_lock lock(the_mutex); the_queue.push(data); lock.unlock(); cond_not_empty.notify_one(); } void push_if_not_full( Data const& data, const unsigned int max ) { boost::mutex::scoped_lock lock(the_mutex); while( the_queue.size() >= max ) { cond_not_full.wait(lock); } the_queue.push(data); lock.unlock(); cond_not_empty.notify_one(); } bool empty() const { boost::mutex::scoped_lock lock(the_mutex); return the_queue.empty(); } typename Container::size_type size() const { return the_queue.size(); } bool try_pop(Data& popped_value) { boost::mutex::scoped_lock lock(the_mutex); if(the_queue.empty()) { return false; } popped_value=the_queue.front(); the_queue.pop(); cond_not_full.notify_one(); return true; } void wait_and_pop( Data &popped_value ) { boost::mutex::scoped_lock lock(the_mutex); while(the_queue.empty()) { cond_not_empty.wait(lock); } popped_value = the_queue.front(); the_queue.pop(); cond_not_full.notify_one(); } }; #endif // __TQUEUE_H__