diff --git a/Core/FileSystems/ISOFileSystem.h b/Core/FileSystems/ISOFileSystem.h index 676964f079..0b8c00512a 100644 --- a/Core/FileSystems/ISOFileSystem.h +++ b/Core/FileSystems/ISOFileSystem.h @@ -19,6 +19,7 @@ #include #include +#include #include "FileSystem.h" @@ -100,7 +101,7 @@ private: // the filenames to "", to achieve this. class ISOBlockSystem : public IFileSystem { public: - ISOBlockSystem(ISOFileSystem *isoFileSystem) : isoFileSystem_(isoFileSystem) {} + ISOBlockSystem(std::shared_ptr isoFileSystem) : isoFileSystem_(isoFileSystem) {} void DoState(PointerWrap &p) override { // This is a bit iffy, as block device savestates already are iffy (loads/saves multiple times for multiple mounts..) @@ -150,5 +151,5 @@ public: bool RemoveFile(const std::string &filename) override { return false; } private: - ISOFileSystem *isoFileSystem_; + std::shared_ptr isoFileSystem_; }; diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index 662d99bad8..b8ebc9238e 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -172,10 +172,11 @@ IFileSystem *MetaFileSystem::GetHandleOwner(u32 handle) for (size_t i = 0; i < fileSystems.size(); i++) { if (fileSystems[i].system->OwnsHandle(handle)) - return fileSystems[i].system; //got it! + return fileSystems[i].system.get(); } - //none found? - return 0; + + // Not found + return nullptr; } int MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpath, MountPoint **system) @@ -274,41 +275,38 @@ std::string MetaFileSystem::NormalizePrefix(std::string prefix) const { return prefix; } -void MetaFileSystem::Mount(std::string prefix, IFileSystem *system) { +void MetaFileSystem::Mount(std::string prefix, std::shared_ptr system) { std::lock_guard guard(lock); + MountPoint x; x.prefix = prefix; x.system = system; + for (auto &it : fileSystems) { + if (it.prefix == prefix) { + // Overwrite the old mount. Don't create a new one. + it = x; + return; + } + } + + // Prefix not yet mounted, do so. fileSystems.push_back(x); } -void MetaFileSystem::Unmount(std::string prefix, IFileSystem *system) { - std::lock_guard guard(lock); - MountPoint x; - x.prefix = prefix; - x.system = system; - fileSystems.erase(std::remove(fileSystems.begin(), fileSystems.end(), x), fileSystems.end()); +void MetaFileSystem::UnmountAll() { + fileSystems.clear(); + currentDir.clear(); } -void MetaFileSystem::Remount(std::string prefix, IFileSystem *newSystem) { +bool MetaFileSystem::Remount(std::string prefix, std::shared_ptr system) { std::lock_guard guard(lock); - IFileSystem *oldSystem = nullptr; for (auto &it : fileSystems) { if (it.prefix == prefix) { - oldSystem = it.system; - it.system = newSystem; + it.system = system; + return true; } } - - bool delOldSystem = true; - for (auto &it : fileSystems) { - if (it.system == oldSystem) { - delOldSystem = false; - } - } - - if (delOldSystem) - delete oldSystem; + return false; } IFileSystem *MetaFileSystem::GetSystemFromFilename(const std::string &filename) { @@ -321,31 +319,16 @@ IFileSystem *MetaFileSystem::GetSystemFromFilename(const std::string &filename) IFileSystem *MetaFileSystem::GetSystem(const std::string &prefix) { for (auto it = fileSystems.begin(); it != fileSystems.end(); ++it) { if (it->prefix == NormalizePrefix(prefix)) - return it->system; + return it->system.get(); } return NULL; } -void MetaFileSystem::Shutdown() -{ +void MetaFileSystem::Shutdown() { std::lock_guard guard(lock); - current = 6; - // Ownership is a bit convoluted. Let's just delete everything once. - - std::set toDelete; - for (size_t i = 0; i < fileSystems.size(); i++) { - toDelete.insert(fileSystems[i].system); - } - - for (auto iter = toDelete.begin(); iter != toDelete.end(); ++iter) - { - delete *iter; - } - - fileSystems.clear(); - currentDir.clear(); - startingDirectory = ""; + UnmountAll(); + Reset(); } int MetaFileSystem::OpenFile(std::string filename, FileAccess access, const char *devicename) diff --git a/Core/FileSystems/MetaFileSystem.h b/Core/FileSystems/MetaFileSystem.h index a1152e1abd..84ea60a44a 100644 --- a/Core/FileSystems/MetaFileSystem.h +++ b/Core/FileSystems/MetaFileSystem.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "Core/FileSystems/FileSystem.h" @@ -28,13 +29,14 @@ private: s32 current; struct MountPoint { std::string prefix; - IFileSystem *system; + std::shared_ptr system; bool operator == (const MountPoint &other) const { return prefix == other.prefix && system == other.system; } }; + // The order of this vector is meaningful - lookups are always a linear search from the start. std::vector fileSystems; typedef std::map currentDir_t; @@ -43,26 +45,34 @@ private: std::string startingDirectory; std::recursive_mutex lock; // must be recursive -public: - MetaFileSystem() { + void Reset() { // This used to be 6, probably an attempt to replicate PSP handles. // However, that's an artifact of using psplink anyway... current = 1; + startingDirectory.clear(); } - void Mount(std::string prefix, IFileSystem *system); - void Unmount(std::string prefix, IFileSystem *system); - void Remount(std::string prefix, IFileSystem *newSystem); +public: + MetaFileSystem() { + Reset(); + } + void Mount(std::string prefix, std::shared_ptr system); + // Fails if there's not already a file system at prefix. + bool Remount(std::string prefix, std::shared_ptr system); + + void UnmountAll(); + + // The pointer returned from these are for temporary usage only. Do not store. IFileSystem *GetSystem(const std::string &prefix); IFileSystem *GetSystemFromFilename(const std::string &filename); + IFileSystem *GetHandleOwner(u32 handle); FileSystemFlags FlagsFromFilename(const std::string &filename) { IFileSystem *sys = GetSystemFromFilename(filename); return sys ? sys->Flags() : FileSystemFlags::NONE; } void ThreadEnded(int threadID); - void Shutdown(); u32 GetNewHandle() override { @@ -77,14 +87,13 @@ public: void DoState(PointerWrap &p) override; - IFileSystem *GetHandleOwner(u32 handle); int MapFilePath(const std::string &inpath, std::string &outpath, MountPoint **system); inline int MapFilePath(const std::string &_inpath, std::string &outpath, IFileSystem **system) { MountPoint *mountPoint; int error = MapFilePath(_inpath, outpath, &mountPoint); if (error == 0) { - *system = mountPoint->system; + *system = mountPoint->system.get(); return error; } diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 73702ae4e3..7128bfa73d 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "Common/Thread/ThreadUtil.h" #include "Common/Profiler/Profiler.h" @@ -557,7 +558,6 @@ static void __IoAsyncEndCallback(SceUID threadID, SceUID prevCallbackId) { } } -static DirectoryFileSystem *memstickSystem = nullptr; static DirectoryFileSystem *exdataSystem = nullptr; #if defined(USING_WIN_UI) || defined(APPLE) static DirectoryFileSystem *flash0System = nullptr; @@ -631,12 +631,15 @@ void __IoInit() { asyncNotifyEvent = CoreTiming::RegisterEvent("IoAsyncNotify", __IoAsyncNotify); syncNotifyEvent = CoreTiming::RegisterEvent("IoSyncNotify", __IoSyncNotify); - memstickSystem = new DirectoryFileSystem(&pspFileSystem, g_Config.memStickDirectory, FileSystemFlags::SIMULATE_FAT32 | FileSystemFlags::CARD); + auto memstickSystem = std::shared_ptr(new DirectoryFileSystem(&pspFileSystem, g_Config.memStickDirectory, FileSystemFlags::SIMULATE_FAT32 | FileSystemFlags::CARD)); #if defined(USING_WIN_UI) || defined(APPLE) - flash0System = new DirectoryFileSystem(&pspFileSystem, g_Config.flash0Directory, FileSystemFlags::FLASH); + auto flash0System = std::shared_ptr(new DirectoryFileSystem(&pspFileSystem, g_Config.flash0Directory, FileSystemFlags::FLASH)); #else - flash0System = new VFSFileSystem(&pspFileSystem, "flash0"); + auto flash0System = std::shared_ptr(new VFSFileSystem(&pspFileSystem, "flash0")); #endif + + // TODO(scoped): This won't work if memStickDirectory points at the contents of /PSP... + // Will fix later with dual mounts (first mount ms0:/PSP/ at memstickSystem), then also mount ms0:/ on it) pspFileSystem.Mount("ms0:", memstickSystem); pspFileSystem.Mount("fatms0:", memstickSystem); pspFileSystem.Mount("fatms:", memstickSystem); @@ -647,7 +650,7 @@ void __IoInit() { const std::string gameId = g_paramSFO.GetDiscID(); const Path exdataPath = GetSysDirectory(DIRECTORY_EXDATA) / gameId; if (File::Exists(exdataPath)) { - exdataSystem = new DirectoryFileSystem(&pspFileSystem, exdataPath, FileSystemFlags::SIMULATE_FAT32 | FileSystemFlags::CARD); + auto exdataSystem = std::shared_ptr(new DirectoryFileSystem(&pspFileSystem, exdataPath, FileSystemFlags::SIMULATE_FAT32 | FileSystemFlags::CARD)); pspFileSystem.Mount("exdata0:", exdataSystem); INFO_LOG(SCEIO, "Mounted exdata/%s/ under memstick for exdata0:/", gameId.c_str()); } else { @@ -763,23 +766,9 @@ void __IoShutdown() { } asyncDefaultPriority = -1; - pspFileSystem.Unmount("ms0:", memstickSystem); - pspFileSystem.Unmount("fatms0:", memstickSystem); - pspFileSystem.Unmount("fatms:", memstickSystem); - pspFileSystem.Unmount("pfat0:", memstickSystem); - pspFileSystem.Unmount("flash0:", flash0System); - - if (g_RemasterMode && exdataSystem) { - pspFileSystem.Unmount("exdata0:", exdataSystem); - delete exdataSystem; - exdataSystem = nullptr; - } - - delete memstickSystem; - memstickSystem = nullptr; - delete flash0System; - flash0System = nullptr; + pspFileSystem.UnmountAll(); + // All the file systems will be removed when we shut down pspFileSystem later. MemoryStick_Shutdown(); memStickCallbacks.clear(); memStickFatCallbacks.clear(); diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index 869c6f8492..73a6a8e746 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -80,11 +80,11 @@ void InitMemoryForGameISO(FileLoader *fileLoader) { return; } - IFileSystem *fileSystem = nullptr; - IFileSystem *blockSystem = nullptr; + std::shared_ptr fileSystem; + std::shared_ptr blockSystem; if (fileLoader->IsDirectory()) { - fileSystem = new VirtualDiscFileSystem(&pspFileSystem, fileLoader->GetPath()); + fileSystem = std::shared_ptr(new VirtualDiscFileSystem(&pspFileSystem, fileLoader->GetPath())); blockSystem = fileSystem; } else { auto bd = constructBlockDevice(fileLoader); @@ -92,9 +92,9 @@ void InitMemoryForGameISO(FileLoader *fileLoader) { if (!bd) return; - ISOFileSystem *iso = new ISOFileSystem(&pspFileSystem, bd); + std::shared_ptr iso = std::shared_ptr(new ISOFileSystem(&pspFileSystem, bd)); fileSystem = iso; - blockSystem = new ISOBlockSystem(iso); + blockSystem = std::shared_ptr(new ISOBlockSystem(iso)); } pspFileSystem.Mount("umd0:", blockSystem); @@ -148,20 +148,20 @@ bool ReInitMemoryForGameISO(FileLoader *fileLoader) { return false; } - IFileSystem *fileSystem = nullptr; - IFileSystem *blockSystem = nullptr; + std::shared_ptr fileSystem; + std::shared_ptr blockSystem; if (fileLoader->IsDirectory()) { - fileSystem = new VirtualDiscFileSystem(&pspFileSystem, fileLoader->GetPath()); + fileSystem = std::shared_ptr(new VirtualDiscFileSystem(&pspFileSystem, fileLoader->GetPath())); blockSystem = fileSystem; } else { auto bd = constructBlockDevice(fileLoader); if (!bd) return false; - ISOFileSystem *iso = new ISOFileSystem(&pspFileSystem, bd); + std::shared_ptr iso = std::shared_ptr(new ISOFileSystem(&pspFileSystem, bd)); fileSystem = iso; - blockSystem = new ISOBlockSystem(iso); + blockSystem = std::shared_ptr(new ISOBlockSystem(iso)); } pspFileSystem.Remount("umd0:", blockSystem); @@ -367,14 +367,15 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) { if (PSP_CoreParameter().mountIsoLoader != nullptr) { auto bd = constructBlockDevice(PSP_CoreParameter().mountIsoLoader); if (bd != NULL) { - ISOFileSystem *umd2 = new ISOFileSystem(&pspFileSystem, bd); - ISOBlockSystem *blockSystem = new ISOBlockSystem(umd2); + std::shared_ptr umd2 = std::shared_ptr(new ISOFileSystem(&pspFileSystem, bd)); + std::shared_ptr blockSystem = std::shared_ptr(new ISOBlockSystem(umd2)); pspFileSystem.Mount("umd1:", blockSystem); pspFileSystem.Mount("disc0:", umd2); pspFileSystem.Mount("umd:", blockSystem); } } + Path full_path = fileLoader->GetPath(); std::string path = full_path.GetDirectory(); std::string extension = full_path.GetFileExtension(); @@ -411,7 +412,7 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) { pspFileSystem.SetStartingDirectory(ms_path); } - DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, Path(path), FileSystemFlags::SIMULATE_FAT32 | FileSystemFlags::CARD); + std::shared_ptr fs = std::shared_ptr(new DirectoryFileSystem(&pspFileSystem, Path(path), FileSystemFlags::SIMULATE_FAT32 | FileSystemFlags::CARD)); pspFileSystem.Mount("umd0:", fs); std::string finalName = ms_path + file; @@ -469,7 +470,7 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) { } bool Load_PSP_GE_Dump(FileLoader *fileLoader, std::string *error_string) { - BlobFileSystem *umd = new BlobFileSystem(&pspFileSystem, fileLoader, "data.ppdmp"); + std::shared_ptr umd = std::shared_ptr(new BlobFileSystem(&pspFileSystem, fileLoader, "data.ppdmp")); pspFileSystem.Mount("disc0:", umd); PSPLoaders_Shutdown(); diff --git a/Core/System.cpp b/Core/System.cpp index aace6ccfa7..b9f2ccf0e8 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -351,6 +351,7 @@ void CPU_Shutdown() { if (coreParameter.enableSound) { Audio_Shutdown(); } + pspFileSystem.Shutdown(); mipsr4k.Shutdown(); Memory::Shutdown();