/** * dequeues the next item from the top of the queue * * @param t assigned to the item at the top of the queue, if it is not empty * @param boost::uint32_t version number of the item retrieved, or head node if none * * @return true if an item was retrieved; false if the queue is empty */ inline bool dequeue(T& t, boost::uint32_t& version) { // just return if the list is empty boost::mutex::scoped_lock head_lock(m_head_mutex); QueueNode *new_head_ptr = m_head_ptr->next; if (! new_head_ptr) { version = m_head_ptr->version; return false; } // get a copy of the item at the head of the list version = new_head_ptr->version; t = new_head_ptr->data; // update the pointer to the head of the list QueueNode *old_head_ptr = m_head_ptr; m_head_ptr = new_head_ptr; head_lock.unlock(); // free the QueueNode for the old head of the list destroyNode(old_head_ptr); // decrement size --m_size; // item successfully dequeued return true; }
std::unique_ptr<node> pop_head() { std::lock_guard<std::mutex> head_lock(_head_mutex); if (_head.get() == get_tail()) return nullptr; std::unique_ptr<node> old_head = std::move(_head); _head = std::move(old_head->next); return old_head; }
std::unique_ptr<node> try_pop_head() { std::lock_guard<std::mutex> head_lock(head_mutex); if (head.get() == get_tail()) { return std::unique_ptr<node>(); } return pop_head(); }
std::unique_ptr<node> try_pop_head(T& value) { std::lock_guard<std::mutex> head_lock(head_mutex); if (head.get() == get_tail()) { return std::unique_ptr<node>(); } value = std::move(*head->data); return pop_head(); }
std::unique_ptr<node> pop_head() { std::lock_guard<std::mutex> head_lock(head_mutex); if(head.get()==get_tail()) { return nullptr; } std::unique_ptr<node> const old_head=std::move(head); head=std::move(old_head->next); return old_head; }
/// clears the list by removing all remaining items void clear(void) { boost::mutex::scoped_lock tail_lock(m_tail_mutex); boost::mutex::scoped_lock head_lock(m_head_mutex); // also delete dummy node and reinitialize it to clear old value while (m_head_ptr) { m_tail_ptr = m_head_ptr; m_head_ptr = m_head_ptr->next; destroyNode(m_tail_ptr); if (m_head_ptr) --m_size; } initialize(); }
std::unique_ptr<node> wait_pop_head(T& value) { std::unique_lock<std::mutex> head_lock(wait_for_data()); value = std::move(*head->data); return pop_head(); }
std::unique_ptr<node> wait_pop_head() { std::unique_lock<std::mutex> head_lock(wait_for_data()); return pop_head(); }
std::unique_lock<std::mutex> wait_for_data() { std::unique_lock<std::mutex> head_lock(head_mutex); data_cond.wait(head_lock, [&]{return head.get() != queue::get_tail();}); return std::move(head_lock); }
void empty() { std::lock_guard<std::mutex> head_lock(head_mutex); return (head.get(0 == get_tail())); }