- };
-public:
- void push(T new_value)
- {
- std::unique_ptr<T> new_data(new T(new_value));
- counted_node_ptr new_next;
- new_next.ptr=new node;
- new_next.external_count=1;
- counted_node_ptr old_tail=tail.load();
- for(;;)
- {
- increase_external_count(tail,old_tail);
- T* old_data=nullptr;
- if(old_tail.ptr->data.compare_exchange_strong(
- old_data,new_data.get()))
- {
- old_tail.ptr->next=new_next;
- old_tail=tail.exchange(new_next);
- free_external_counter(old_tail);
- new_data.release();
- break;
- }
- old_tail.ptr->release_ref();
- }
- }
-};
-
-
-// ./listing_7.16.cpp
-
-template<typename T>
-class lock_free_queue
-{
-private:
- struct node
- {
- void release_ref();
- };
-public:
- 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)
- {
- ptr->release_ref();
- return std::unique_ptr<T>();
- }
- if(head.compare_exchange_strong(old_head,ptr->next))
- {
- T* const res=ptr->data.exchange(nullptr);
- free_external_counter(old_head);
- return std::unique_ptr<T>(res);
- }
- ptr->release_ref();
- }
- }
-};
-
-
-// ./listing_7.17.cpp
-
-template<typename T>
-class lock_free_queue
-{
-private:
- struct node
- {