diff --git a/AK/WeakPtr.h b/AK/WeakPtr.h index f31004f7cd..210ffc9714 100644 --- a/AK/WeakPtr.h +++ b/AK/WeakPtr.h @@ -153,40 +153,10 @@ template template inline WeakPtr Weakable::make_weak_ptr() const { - if constexpr (IsBaseOf) { - // Checking m_being_destroyed isn't sufficient when dealing with - // a RefCounted type.The reference count will drop to 0 before the - // destructor is invoked and revoke_weak_ptrs is called. So, try - // to add a ref (which should fail if the ref count is at 0) so - // that we prevent the destructor and revoke_weak_ptrs from being - // triggered until we're done. - if (!static_cast(this)->try_ref()) - return {}; - } else { - // For non-RefCounted types this means a weak reference can be - // obtained until the ~Weakable destructor is invoked! - if (m_being_destroyed.load(AK::MemoryOrder::memory_order_acquire)) - return {}; - } - if (!m_link) { - // There is a small chance that we create a new WeakLink and throw - // it away because another thread beat us to it. But the window is - // pretty small and the overhead isn't terrible. - m_link.assign_if_null(adopt_ref(*new WeakLink(const_cast(static_cast(*this))))); - } + if (!m_link) + m_link = adopt_ref(*new WeakLink(const_cast(static_cast(*this)))); - WeakPtr weak_ptr(m_link); - - if constexpr (IsBaseOf) { - // Now drop the reference we temporarily added - if (static_cast(this)->unref()) { - // We just dropped the last reference, which should have called - // revoke_weak_ptrs, which should have invalidated our weak_ptr - VERIFY(!weak_ptr.strong_ref()); - return {}; - } - } - return weak_ptr; + return WeakPtr(m_link); } template diff --git a/AK/Weakable.h b/AK/Weakable.h index 1e246563e2..c3ee850520 100644 --- a/AK/Weakable.h +++ b/AK/Weakable.h @@ -113,7 +113,9 @@ protected: ~Weakable() { +#ifdef KERNEL m_being_destroyed.store(true, AK::MemoryOrder::memory_order_release); +#endif revoke_weak_ptrs(); } @@ -125,7 +127,9 @@ protected: private: mutable RefPtr m_link; +#ifdef KERNEL Atomic m_being_destroyed { false }; +#endif }; }