Posted March 3Mar 3 When using std::atomic<std::shared_ptr<T>>, the C++ standard defines a "change" as a modification to either the stored pointer or the control block pointer. However, since atomic wait mechanisms typically track only a single memory address, the Microsoft implementation handles this limitation by using a timeout-based polling strategy to detect changes in the control block. Inside STL: Waiting for a std::atomic<std::shared_ptr<T>> to change, part 1 by Raymond Chen From the article: Like other std::atomic specializations, std::atomic<std::shared_ptr<T>> supports the wait and notify_* methods for waiting for the value to change and reporting that the value has changed. The definition of “changed” in the C++ language specification is that the value has changed if either the stored pointer or the control block pointer has changed. A shared pointer is implemented as a pair of pointers, but Wait­On­Address can wait on at most 8 bytes, and unix futexes can wait on only four bytes, so how does this work?¹ The Microsoft implementation waits for the stored pointer to change, and the notify_* methods signal the stored pointer. But wait, this fails to detect the case where the stored pointer stays the same and only the control block changes. std::atomic<std::shared_ptr<int>> p = std::make_shared<int>(42); void change_control_block() { auto old = p.load(); auto empty = std::shared_ptr<int>(); // Replace with an indulgent shared pointer // with the same stored pointer. p.store({ empty, old.get() }); p.notify_all(); } void wait_for_change() { auto old = p.load(); p.wait(old); } View the full article
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.