aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-11-01 12:18:19 -0500
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-11-01 12:18:19 -0500
commiteca63ccb1006fdec79f6392d38bd74739e1371df (patch)
tree1dda944f21d033fab85f04c8c5c0b61a68978f0a /src/core
parent6bde8c20d1f7c020a920e59a989c03822a08445d (diff)
vfs_real: forget a path when its file is gone
The path cache holds weak references, but nothing erased an entry once its file was destroyed, so every path ever opened stayed in the cache until the filesystem was destroyed (title 1's loose RomFS: 206k paths, 24 MB of keys, kept after the game stops). The entry is erased when the file's last reference is dropped, unless the path was opened again meanwhile.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/file_sys/vfs/vfs_real.cpp10
-rw-r--r--src/core/file_sys/vfs/vfs_real.h2
2 files changed, 9 insertions, 3 deletions
diff --git a/src/core/file_sys/vfs/vfs_real.cpp b/src/core/file_sys/vfs/vfs_real.cpp
index 5b5b54017c..e178bcab58 100644
--- a/src/core/file_sys/vfs/vfs_real.cpp
+++ b/src/core/file_sys/vfs/vfs_real.cpp
@@ -257,7 +257,8 @@ std::unique_lock<std::mutex> RealVfsFilesystem::RefreshReference(const std::stri
return lk;
}
-void RealVfsFilesystem::DropReference(std::unique_ptr<FileReference>&& reference) {
+void RealVfsFilesystem::DropReference(std::unique_ptr<FileReference>&& reference,
+ const std::string& path) {
if (in_dtor)
return;
@@ -266,6 +267,11 @@ void RealVfsFilesystem::DropReference(std::unique_ptr<FileReference>&& reference
// Remove from list.
this->RemoveReferenceFromListLocked(*reference);
+ // Forget the path, unless it was opened again since this file's last reference went away.
+ if (const auto it = cache.find(path); it != cache.end() && it->second.expired()) {
+ cache.erase(it);
+ }
+
// Close the file.
if (reference->file) {
reference->file.reset();
@@ -316,7 +322,7 @@ RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::unique_ptr<FileReference
path_components(FS::SplitPathComponentsCopy(path_)), size(size_), perms(perms_) {}
RealVfsFile::~RealVfsFile() {
- base.DropReference(std::move(reference));
+ base.DropReference(std::move(reference), path);
}
std::string RealVfsFile::GetName() const {
diff --git a/src/core/file_sys/vfs/vfs_real.h b/src/core/file_sys/vfs/vfs_real.h
index a97f7d32ea..9c769c667c 100644
--- a/src/core/file_sys/vfs/vfs_real.h
+++ b/src/core/file_sys/vfs/vfs_real.h
@@ -62,7 +62,7 @@ private:
friend class RealVfsFile;
std::unique_lock<std::mutex> RefreshReference(const std::string& path, OpenMode perms,
FileReference& reference);
- void DropReference(std::unique_ptr<FileReference>&& reference);
+ void DropReference(std::unique_ptr<FileReference>&& reference, const std::string& path);
private:
friend class RealVfsDirectory;