diff --git a/AK/Weakable.h b/AK/Weakable.h index 4dd3d8d813..1c90ba595b 100644 --- a/AK/Weakable.h +++ b/AK/Weakable.h @@ -7,11 +7,9 @@ #pragma once #include -#include #include #include #include -#include namespace AK { @@ -31,50 +29,18 @@ public: RefPtr strong_ref() const requires(IsBaseOf) { - RefPtr ref; - - { - if (!(m_consumers.fetch_add(1u << 1, AK::MemoryOrder::memory_order_acquire) & 1u)) { - T* ptr = (T*)m_ptr.load(AK::MemoryOrder::memory_order_acquire); - if (ptr && ptr->try_ref()) - ref = adopt_ref(*ptr); - } - m_consumers.fetch_sub(1u << 1, AK::MemoryOrder::memory_order_release); - } - - return ref; + return static_cast(m_ptr); } template T* unsafe_ptr() const { - if (m_consumers.load(AK::MemoryOrder::memory_order_relaxed) & 1u) - return nullptr; - // NOTE: This may return a non-null pointer even if revocation - // has been triggered as there is a possible race! But it's "unsafe" - // anyway because we return a raw pointer without ensuring a - // reference... - return (T*)m_ptr.load(AK::MemoryOrder::memory_order_acquire); + return static_cast(m_ptr); } - bool is_null() const - { - return unsafe_ptr() == nullptr; - } + bool is_null() const { return m_ptr == nullptr; } - void revoke() - { - auto current_consumers = m_consumers.fetch_or(1u, AK::MemoryOrder::memory_order_relaxed); - VERIFY(!(current_consumers & 1u)); - // We flagged revocation, now wait until everyone trying to obtain - // a strong reference is done - while (current_consumers > 0) { - sched_yield(); - current_consumers = m_consumers.load(AK::MemoryOrder::memory_order_acquire) & ~1u; - } - // No one is trying to use it (anymore) - m_ptr.store(nullptr, AK::MemoryOrder::memory_order_release); - } + void revoke() { m_ptr = nullptr; } private: template @@ -82,8 +48,8 @@ private: : m_ptr(&weakable) { } - mutable Atomic m_ptr; - mutable Atomic m_consumers; // LSB indicates revocation in progress + + mutable void* m_ptr { nullptr }; }; template