/* * Copyright (c) 2021, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include namespace Kernel { // ListedRefCounted is a slot-in replacement for RefCounted to use in classes // that add themselves to a SpinlockProtected when constructed. // The custom unref() implementation here ensures that the the list is locked during // unref(), and that the T is removed from the list before ~T() is invoked. template class ListedRefCounted : public RefCountedBase { public: bool unref() const { auto new_ref_count = T::all_instances().with([&](auto& list) { auto new_ref_count = deref_base(); if (new_ref_count == 0) list.remove(const_cast(static_cast(*this))); return new_ref_count; }); if (new_ref_count == 0) { call_will_be_destroyed_if_present(static_cast(this)); delete const_cast(static_cast(this)); } else if (new_ref_count == 1) { call_one_ref_left_if_present(static_cast(this)); } return new_ref_count == 0; } }; }