Skip to content
This repository has been archived by the owner on Jan 6, 2022. It is now read-only.

Wrong conditions in retain_traits::decrement #8

Open
KalleOlaviNiemitalo opened this issue May 1, 2019 · 0 comments
Open

Wrong conditions in retain_traits::decrement #8

KalleOlaviNiemitalo opened this issue May 1, 2019 · 0 comments

Comments

@KalleOlaviNiemitalo
Copy link

In template <class T> struct retain_traits, the decrement functions seem to delete the object in the wrong situations:

  static void decrement (atomic_reference_count<T>* ptr) noexcept {
    ptr->count.fetch_sub(1, std::memory_order_acq_rel);
    if (not use_count(ptr)) { delete static_cast<T*>(ptr); }
}

Suppose you have two retain_ptr smart pointers pointing to the same object and its reference count is 2. Then, both retain_ptr smart pointers are destructed in different threads. In each thread, fetch_sub decrements the reference count, so it goes from 2 to 1 and then to 0. Then in each thread, use_count returns 0 and both threads delete the same object. decrement should instead check what value fetch_sub returned, so that only the thread that changed the reference count to 0 deletes the object.

  static void decrement (reference_count<T>* ptr) noexcept {
    if (ptr->count -= 1) { delete static_cast<T*>(ptr); }
}

This seems to delete the object when the reference count decreases to any nonzero value. It should delete when the reference count decreases to zero. Commit 898a4fd in PR #6 fixes that.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant