私は、C++ 11 の Anthony Williams Concurrency book に取り組んでいます。
ロックフリースタックの pop 実装に少し混乱しています。
template<typename T>
class lock_free_stack
{
private:
struct node
{
std::shared_ptr<T> data;
node* next;
node(T const& data_): data( std::make_shared<T>(data_)){}
};
std::atomic<node*> head;
public:
void push(T const& data)
{
node* const new_node = new node(data);
new_node->next = head.load();
while(!head.compare_exchange_weak(new_node->next, new_node));
}
std::shared_ptr<T> pop()
{
node* old_head = head.load();
while( old_head && !head.compare_exchange_weak(old_head, old_head->next));
// Does This not return the data of the next node before the head if
// compare_exchange_weak returns true
return old_head ? old_head->data : std::shared_ptr<T>();
}
};
私を混乱させているのは pop 関数の最後の 2 行です。
while( old_head && !head.compare_exchange_weak(old_head, old_head->next));
return old_head ? old_head->data : std::shared_ptr<T>();
true を返した場合、compare_exchange_weak 関数は old_head をスタック内の次のノードに変更しませんか? これにより、old_head が nullptr でない場合、return ステートメントはスタックの一番上にある古いヘッドではなく、次のノードからデータを返します。
これを間違って解釈しましたか?