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 (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();
|
||||
|
||||
// Release the bias - decrement weak count for strong references
|
||||
@@ -304,6 +306,10 @@ private:
|
||||
* - Returns empty Ref<T> if object was already destroyed
|
||||
* - 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
|
||||
* 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());
|
||||
}
|
||||
}
|
||||
|
||||
// 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