diff --git a/Kernel/FileSystem/Inode.h b/Kernel/FileSystem/Inode.h index acc58eee7a..75ecc8f9e5 100644 --- a/Kernel/FileSystem/Inode.h +++ b/Kernel/FileSystem/Inode.h @@ -23,7 +23,7 @@ namespace Kernel { -class Inode : public ListedRefCounted +class Inode : public ListedRefCounted , public Weakable { friend class VirtualFileSystem; friend class FileSystem; diff --git a/Kernel/Library/ListedRefCounted.h b/Kernel/Library/ListedRefCounted.h index d0cabd75ba..0f84b905d2 100644 --- a/Kernel/Library/ListedRefCounted.h +++ b/Kernel/Library/ListedRefCounted.h @@ -11,21 +11,32 @@ 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 +// that add themselves to a {Spinlock, Mutex}Protected when constructed. +// The custom unref() implementation here ensures that the list is locked during // unref(), and that the T is removed from the list before ~T() is invoked. -template +enum class LockType { + Spinlock, + Mutex, +}; + +template class ListedRefCounted : public RefCountedBase { public: bool unref() const { - auto new_ref_count = T::all_instances().with([&](auto& list) { + auto callback = [&](auto& list) { auto new_ref_count = deref_base(); if (new_ref_count == 0) list.remove(const_cast(static_cast(*this))); return new_ref_count; - }); + }; + + RefCountType new_ref_count; + if constexpr (Lock == LockType::Spinlock) + new_ref_count = T::all_instances().with(callback); + else if constexpr (Lock == LockType::Mutex) + new_ref_count = T::all_instances().with_exclusive(callback); if (new_ref_count == 0) { call_will_be_destroyed_if_present(static_cast(this)); delete const_cast(static_cast(this)); diff --git a/Kernel/Memory/VMObject.h b/Kernel/Memory/VMObject.h index 2cfa03f8aa..7997b86cf2 100644 --- a/Kernel/Memory/VMObject.h +++ b/Kernel/Memory/VMObject.h @@ -18,7 +18,7 @@ namespace Kernel::Memory { class VMObject - : public ListedRefCounted + : public ListedRefCounted , public Weakable { friend class MemoryManager; friend class Region; diff --git a/Kernel/Thread.h b/Kernel/Thread.h index 454dc7749e..131053162b 100644 --- a/Kernel/Thread.h +++ b/Kernel/Thread.h @@ -146,7 +146,7 @@ struct ThreadRegisters { }; class Thread - : public ListedRefCounted + : public ListedRefCounted , public Weakable { AK_MAKE_NONCOPYABLE(Thread); AK_MAKE_NONMOVABLE(Thread);