1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 20:37:34 +00:00

Automatically call Inode::flush_metadata() before an Inode is destroyed.

Use a little template magic to have Retainable::release() call out to
T::will_be_destroyed() if such a function exists before actually calling
the destructor. This gives us full access to virtual functions in the
pre-destruction code.
This commit is contained in:
Andreas Kling 2018-12-19 22:28:09 +01:00
parent 1f44cd9dd9
commit d0f06e5f3f
6 changed files with 41 additions and 17 deletions

View file

@ -1,39 +1,54 @@
#pragma once
#include "Assertions.h"
#include "StdLibExtras.h"
namespace AK {
template<class T>
constexpr auto call_will_be_destroyed_if_present(T* object) -> decltype(object->will_be_destroyed(), TrueType { })
{
object->will_be_destroyed();
return { };
}
constexpr auto call_will_be_destroyed_if_present(...) -> FalseType
{
return { };
}
template<typename T>
class Retainable {
public:
void retain()
{
ASSERT(m_retainCount);
++m_retainCount;
ASSERT(m_retain_count);
++m_retain_count;
}
void release()
{
ASSERT(m_retainCount);
if (!--m_retainCount)
ASSERT(m_retain_count);
if (!--m_retain_count) {
call_will_be_destroyed_if_present(static_cast<T*>(this));
delete static_cast<T*>(this);
}
}
int retainCount() const
int retain_count() const
{
return m_retainCount;
return m_retain_count;
}
protected:
Retainable() { }
~Retainable()
{
ASSERT(!m_retainCount);
ASSERT(!m_retain_count);
}
private:
int m_retainCount { 1 };
int m_retain_count { 1 };
};
}