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:
parent
1f44cd9dd9
commit
d0f06e5f3f
6 changed files with 41 additions and 17 deletions
|
@ -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 };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue