summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-02-08 16:40:48 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-02-08 16:40:48 +0100
commitd4ba15571105723e2bf8120e5cf8ca440261029c (patch)
tree481795f9c7f62ae8aa24636f694fa24767f48239
parente1be5a468dece00603de4722d50916b21d2a83e8 (diff)
downloadserenity-d4ba15571105723e2bf8120e5cf8ca440261029c.zip
Kernel: Break retain cycle between Inode and VMObject.
There's no need for an Inode to keep its corresponding VMObject alive. Obviously there are huge benefits to keeping a filesystem cache, but leaking everything is hardly the right strategy. :^)
-rw-r--r--Kernel/FileSystem.cpp4
-rw-r--r--Kernel/FileSystem.h5
-rw-r--r--Kernel/MemoryManager.cpp6
-rw-r--r--Kernel/MemoryManager.h3
4 files changed, 9 insertions, 9 deletions
diff --git a/Kernel/FileSystem.cpp b/Kernel/FileSystem.cpp
index 953ef55abe..75e6a83e04 100644
--- a/Kernel/FileSystem.cpp
+++ b/Kernel/FileSystem.cpp
@@ -148,7 +148,7 @@ void FS::sync()
}
}
-void Inode::set_vmo(RetainPtr<VMObject>&& vmo)
+void Inode::set_vmo(VMObject& vmo)
{
- m_vmo = move(vmo);
+ m_vmo = vmo.make_weak_ptr();
}
diff --git a/Kernel/FileSystem.h b/Kernel/FileSystem.h
index 58a24d25cb..eab654ac51 100644
--- a/Kernel/FileSystem.h
+++ b/Kernel/FileSystem.h
@@ -14,6 +14,7 @@
#include <AK/Function.h>
#include <AK/kstdio.h>
#include <AK/Lock.h>
+#include <AK/WeakPtr.h>
static const dword mepoch = 476763780;
@@ -103,7 +104,7 @@ public:
void will_be_destroyed();
- void set_vmo(RetainPtr<VMObject>&&);
+ void set_vmo(VMObject&);
VMObject* vmo() { return m_vmo.ptr(); }
const VMObject* vmo() const { return m_vmo.ptr(); }
@@ -118,7 +119,7 @@ protected:
private:
FS& m_fs;
unsigned m_index { 0 };
- RetainPtr<VMObject> m_vmo;
+ WeakPtr<VMObject> m_vmo;
bool m_metadata_dirty { false };
};
diff --git a/Kernel/MemoryManager.cpp b/Kernel/MemoryManager.cpp
index 7f70203959..76dacee97c 100644
--- a/Kernel/MemoryManager.cpp
+++ b/Kernel/MemoryManager.cpp
@@ -667,7 +667,7 @@ RetainPtr<VMObject> VMObject::create_file_backed(RetainPtr<Inode>&& inode)
if (inode->vmo())
return static_cast<VMObject*>(inode->vmo());
auto vmo = adopt(*new VMObject(move(inode)));
- vmo->inode()->set_vmo(vmo.ptr());
+ vmo->inode()->set_vmo(*vmo);
return vmo;
}
@@ -732,10 +732,8 @@ VMObject::VMObject(RetainPtr<Inode>&& inode)
VMObject::~VMObject()
{
- if (m_inode) {
+ if (m_inode)
ASSERT(m_inode->vmo() == this);
- m_inode->set_vmo(nullptr);
- }
MM.unregister_vmo(*this);
}
diff --git a/Kernel/MemoryManager.h b/Kernel/MemoryManager.h
index b5974c3d67..a7243d5b97 100644
--- a/Kernel/MemoryManager.h
+++ b/Kernel/MemoryManager.h
@@ -10,6 +10,7 @@
#include <AK/HashTable.h>
#include <AK/AKString.h>
#include <AK/Badge.h>
+#include <AK/Weakable.h>
#include <Kernel/VirtualFileSystem.h>
#define PAGE_ROUND_UP(x) ((((dword)(x)) + PAGE_SIZE-1) & (~(PAGE_SIZE-1)))
@@ -77,7 +78,7 @@ private:
HashMap<unsigned, RetainPtr<PhysicalPage>> m_physical_pages;
};
-class VMObject : public Retainable<VMObject> {
+class VMObject : public Retainable<VMObject>, public Weakable<VMObject> {
friend class MemoryManager;
public:
static RetainPtr<VMObject> create_file_backed(RetainPtr<Inode>&&);