Explicitly support having a WeakRef to self
This commit is contained in:
@@ -270,6 +270,8 @@ private:
|
|||||||
|
|
||||||
// If this was the last strong reference, destroy the object
|
// If this was the last strong reference, destroy the object
|
||||||
if (prev_strong == 1) {
|
if (prev_strong == 1) {
|
||||||
|
// We need to call the destructor before we decrement the weak count, to
|
||||||
|
// account for the possibility that T has a WeakRef to itself.
|
||||||
ptr->~T();
|
ptr->~T();
|
||||||
|
|
||||||
// Release the bias - decrement weak count for strong references
|
// Release the bias - decrement weak count for strong references
|
||||||
@@ -304,6 +306,10 @@ private:
|
|||||||
* - Returns empty Ref<T> if object was already destroyed
|
* - Returns empty Ref<T> if object was already destroyed
|
||||||
* - Use reset() to stop observing
|
* - Use reset() to stop observing
|
||||||
*
|
*
|
||||||
|
* Self-referencing pattern: Objects can safely contain WeakRef members
|
||||||
|
* pointing to themselves. The implementation ensures proper destruction
|
||||||
|
* order to prevent use-after-free when the object destructor runs.
|
||||||
|
*
|
||||||
* Thread safety: All operations are thread-safe. The observed object
|
* Thread safety: All operations are thread-safe. The observed object
|
||||||
* may be destroyed by other threads at any time.
|
* may be destroyed by other threads at any time.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -445,3 +445,17 @@ TEST_CASE("Polymorphic edge cases") {
|
|||||||
CHECK(base_ref_from_weak.get() == derived_ref.get());
|
CHECK(base_ref_from_weak.get() == derived_ref.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Should be run with asan or valgrind
|
||||||
|
TEST_CASE("Self-referencing WeakRef pattern") {
|
||||||
|
struct AmIAlive {
|
||||||
|
volatile int x;
|
||||||
|
~AmIAlive() { x = 0; }
|
||||||
|
};
|
||||||
|
struct SelfReferencing {
|
||||||
|
AmIAlive am;
|
||||||
|
WeakRef<SelfReferencing> self_;
|
||||||
|
};
|
||||||
|
auto x = make_ref<SelfReferencing>();
|
||||||
|
x->self_ = x;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user