In the book C++ Concurrency in Action, the author gave an example of using hazard pointer to implement a lock-free stack data structure. Part of the code is as follows:
std::shared_ptr<T> pop()
{
std::atomic<void*>& hp=get_hazard_pointer_for_current_thread();
node* old_head=head.load();
node* temp;
do
{
temp=old_head;
hp.store(old_head);
old_head=head.load();
} while(old_head!=temp);
// ...
}
The description says that
You have to do this in a
whileloop to ensure that thenodehasn’t been deleted between the reading of the oldheadpointer and the setting of the hazard pointer. During this window no other thread knows you’re accessing this particular node. Fortunately, if the oldheadnode is going to be deleted,headitself must have changed, so you can check this and keep looping until you know that theheadpointer still has the same value you set your hazard pointer to.
I think the code is flawed because the head node is subject to the ABA problem. Even if the value of head remains the same, the node it originally points to may have been deleted. A new head node is allocated, which happens to have the same address value as the previous one.