ListedRefCounted.h 975 B

1234567891011121314151617181920212223242526272829303132333435
  1. /*
  2. * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/RefCounted.h>
  8. namespace Kernel {
  9. // ListedRefCounted<T> is a slot-in replacement for RefCounted<T> to use in classes
  10. // that add themselves to a SpinlockProtected<IntrusiveList> when constructed.
  11. // The custom unref() implementation here ensures that the the list is locked during
  12. // unref(), and that the T is removed from the list before ~T() is invoked.
  13. template<typename T>
  14. class ListedRefCounted : public RefCountedBase {
  15. public:
  16. bool unref() const
  17. {
  18. bool did_hit_zero = T::all_instances().with([&](auto& list) {
  19. if (deref_base())
  20. return false;
  21. list.remove(const_cast<T&>(static_cast<T const&>(*this)));
  22. return true;
  23. });
  24. if (did_hit_zero)
  25. delete const_cast<T*>(static_cast<T const*>(this));
  26. return did_hit_zero;
  27. }
  28. };
  29. }