void set_new_tail(counted_node_ptr &old_tail, counted_node_ptr const &new_tail) { node * const current_tail_ptr = old_tail.get(); while (!tail.compare_exchange_weak(old_tail, new_tail) && old_tail.get() == current_tail_ptr) {} if (old_tail.get() == current_tail_ptr) { free_external_counter(old_tail); return; } if (!current_tail_ptr->release_ref()) deallocate_node(current_tail_ptr); }
stored_ptr pop() { counted_node_ptr old_head = head.load(std::memory_order_relaxed); for (;;) { increase_external_count(head, old_head); node * const ptr = old_head.get(); if (ptr == tail.load().get()) return nullptr; counted_node_ptr next = ptr->next.load(); if (head.compare_exchange_strong(old_head, next)) { T * const res = ptr->data.exchange(nullptr); free_external_counter(old_head); return stored_ptr(res); } if (!ptr->release_ref()) deallocate_node(ptr); } }
std::unique_ptr<T> pop() { counted_node_ptr old_head=head.load(std::memory_order_relaxed); for(;;) { increase_external_count(head,old_head); node* const ptr=old_head.ptr; if(ptr==tail.load().ptr) { return std::unique_ptr<T>(); } counted_node_ptr next=ptr->next.load(); if(head.compare_exchange_strong(old_head,next)) { T* const res=ptr->data.exchange(nullptr); free_external_counter(old_head); return std::unique_ptr<T>(res); } ptr->release_ref(); } }