diff options
author | Chris Robinson <[email protected]> | 2024-01-02 03:26:37 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2024-01-02 03:26:37 -0800 |
commit | 69ac4a4a9d9e0bc8a62b09d939e2a67f83e5544d (patch) | |
tree | 3f9e4e70928d4a2d2de96047a8a4ab0f419a97c7 /common/atomic.h | |
parent | 70a8cf88041d88c49dcd258587e6b84960752851 (diff) |
Use an atomic exchange to destruct the atomic unique_ptr
A relaxed load isn't required to synchronize with other threads. A thread could
exchange the held pointer, and a subsequent load is allowed to get either the
pre- or post-swap value (it's only required the value be "complete", not junk
or some mix of the old and new value). An exchange, however, is guaranteed to
synchronize with itself. If an atomic variable has the value 0, for example,
with one thread swapping in the value 1 and another the value 2, the two
threads are guaranteed to not both get 0 from the swap.
Diffstat (limited to 'common/atomic.h')
-rw-r--r-- | common/atomic.h | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/common/atomic.h b/common/atomic.h index 51ddaa5d..8e75cb0e 100644 --- a/common/atomic.h +++ b/common/atomic.h @@ -41,7 +41,11 @@ public: explicit atomic_unique_ptr(std::nullptr_t) noexcept { } explicit atomic_unique_ptr(gsl::owner<T*> ptr) noexcept : mPointer{ptr} { } explicit atomic_unique_ptr(std::unique_ptr<T>&& rhs) noexcept : mPointer{rhs.release()} { } - ~atomic_unique_ptr() { if(auto ptr = mPointer.load(std::memory_order_relaxed)) D{}(ptr); } + ~atomic_unique_ptr() + { + if(auto ptr = mPointer.exchange(nullptr, std::memory_order_relaxed)) + D{}(ptr); + } atomic_unique_ptr& operator=(const atomic_unique_ptr&) = delete; atomic_unique_ptr& operator=(std::nullptr_t) noexcept |