diff --git a/AK/WeakPtr.h b/AK/WeakPtr.h index ded5a0d0c7..cfd3da2d49 100644 --- a/AK/WeakPtr.h +++ b/AK/WeakPtr.h @@ -151,10 +151,10 @@ private: template template -inline WeakPtr Weakable::make_weak_ptr() const +inline ErrorOr> Weakable::try_make_weak_ptr() const { if (!m_link) - m_link = adopt_ref(*new WeakLink(const_cast(static_cast(*this)))); + m_link = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) WeakLink(const_cast(static_cast(*this))))); return WeakPtr(m_link); } @@ -168,12 +168,18 @@ struct Formatter> : Formatter { }; template -WeakPtr make_weak_ptr_if_nonnull(const T* ptr) +ErrorOr> try_make_weak_ptr_if_nonnull(T const* ptr) { if (ptr) { - return ptr->template make_weak_ptr(); + return ptr->template try_make_weak_ptr(); } - return {}; + return WeakPtr {}; +} + +template +WeakPtr make_weak_ptr_if_nonnull(T const* ptr) +{ + return MUST(try_make_weak_ptr_if_nonnull(ptr)); } } diff --git a/AK/Weakable.h b/AK/Weakable.h index c3ee850520..c800be9205 100644 --- a/AK/Weakable.h +++ b/AK/Weakable.h @@ -106,7 +106,9 @@ private: public: template - WeakPtr make_weak_ptr() const; + WeakPtr make_weak_ptr() const { return MUST(try_make_weak_ptr()); } + template + ErrorOr> try_make_weak_ptr() const; protected: Weakable() = default; diff --git a/Kernel/Library/ThreadSafeWeakPtr.h b/Kernel/Library/ThreadSafeWeakPtr.h index aec6e10970..5768f9b0a8 100644 --- a/Kernel/Library/ThreadSafeWeakPtr.h +++ b/Kernel/Library/ThreadSafeWeakPtr.h @@ -177,7 +177,7 @@ private: template template -inline WeakPtr Weakable::make_weak_ptr() const +inline ErrorOr> Weakable::try_make_weak_ptr() const { if constexpr (IsBaseOf) { // Checking m_being_destroyed isn't sufficient when dealing with @@ -187,18 +187,18 @@ inline WeakPtr Weakable::make_weak_ptr() const // that we prevent the destructor and revoke_weak_ptrs from being // triggered until we're done. if (!static_cast(this)->try_ref()) - return {}; + return WeakPtr {}; } 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 {}; + return WeakPtr {}; } 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))))); + m_link.assign_if_null(TRY(adopt_nonnull_ref_or_enomem(new (nothrow) WeakLink(const_cast(static_cast(*this)))))); } WeakPtr weak_ptr(m_link); @@ -209,7 +209,7 @@ inline WeakPtr Weakable::make_weak_ptr() const // 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 WeakPtr {}; } } return weak_ptr; @@ -229,12 +229,18 @@ struct Formatter> : Formatter { }; template -WeakPtr make_weak_ptr_if_nonnull(const T* ptr) +ErrorOr> try_make_weak_ptr_if_nonnull(T const* ptr) { if (ptr) { - return ptr->template make_weak_ptr(); + return ptr->template try_make_weak_ptr(); } - return {}; + return WeakPtr {}; +} + +template +WeakPtr make_weak_ptr_if_nonnull(T const* ptr) +{ + return MUST(try_make_weak_ptr_if_nonnull(ptr)); } }