summaryrefslogtreecommitdiff
path: root/AK
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-01-01 02:38:09 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-01-01 02:38:09 +0100
commit741349502fabf89a9da7b2696c6214bd8a028d63 (patch)
tree87bb0e0914c1dfa4feb857495ba4cc4e69a1e06f /AK
parent42d9f18caeb9408e820989fda7fef3eb22c70a6e (diff)
downloadserenity-741349502fabf89a9da7b2696c6214bd8a028d63.zip
Ext2FS: Free Ext2FSInodes when the last user releases them.
The inode cache was keeping these alive forever. Added a cute little magic trick to Retainable that calls T::one_retain_left() when the retain count is decremented to 1.
Diffstat (limited to 'AK')
-rw-r--r--AK/Retainable.h17
1 files changed, 16 insertions, 1 deletions
diff --git a/AK/Retainable.h b/AK/Retainable.h
index 05757bea7e..b14ca56a24 100644
--- a/AK/Retainable.h
+++ b/AK/Retainable.h
@@ -17,6 +17,18 @@ constexpr auto call_will_be_destroyed_if_present(...) -> FalseType
return { };
}
+template<class T>
+constexpr auto call_one_retain_left_if_present(T* object) -> decltype(object->one_retain_left(), TrueType { })
+{
+ object->one_retain_left();
+ return { };
+}
+
+constexpr auto call_one_retain_left_if_present(...) -> FalseType
+{
+ return { };
+}
+
template<typename T>
class Retainable {
public:
@@ -29,9 +41,12 @@ public:
void release()
{
ASSERT(m_retain_count);
- if (!--m_retain_count) {
+ --m_retain_count;
+ if (m_retain_count == 0) {
call_will_be_destroyed_if_present(static_cast<T*>(this));
delete static_cast<T*>(this);
+ } else if (m_retain_count == 1) {
+ call_one_retain_left_if_present(static_cast<T*>(this));
}
}