Merge pull request #14638 from hrydgard/metafilesystem-cleanup

Cleanup the ownership model in MetaFileSystem.
This commit is contained in:
Henrik Rydgård 2021-07-25 14:02:46 +02:00 committed by GitHub
commit e9f19e133b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 73 additions and 89 deletions

View file

@ -19,6 +19,7 @@
#include <map>
#include <list>
#include <memory>
#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<IFileSystem> 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<IFileSystem> isoFileSystem_;
};

View file

@ -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<IFileSystem> system) {
std::lock_guard<std::recursive_mutex> 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<std::recursive_mutex> 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<IFileSystem> system) {
std::lock_guard<std::recursive_mutex> 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<std::recursive_mutex> guard(lock);
current = 6;
// Ownership is a bit convoluted. Let's just delete everything once.
std::set<IFileSystem *> 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)

View file

@ -20,6 +20,7 @@
#include <string>
#include <vector>
#include <mutex>
#include <memory>
#include "Core/FileSystems/FileSystem.h"
@ -28,13 +29,14 @@ private:
s32 current;
struct MountPoint {
std::string prefix;
IFileSystem *system;
std::shared_ptr<IFileSystem> 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<MountPoint> fileSystems;
typedef std::map<int, std::string> 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<IFileSystem> system);
// Fails if there's not already a file system at prefix.
bool Remount(std::string prefix, std::shared_ptr<IFileSystem> 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;
}

View file

@ -18,6 +18,7 @@
#include <cstdlib>
#include <set>
#include <thread>
#include <memory>
#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<IFileSystem>(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<IFileSystem>(new DirectoryFileSystem(&pspFileSystem, g_Config.flash0Directory, FileSystemFlags::FLASH));
#else
flash0System = new VFSFileSystem(&pspFileSystem, "flash0");
auto flash0System = std::shared_ptr<IFileSystem>(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<IFileSystem>(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();

View file

@ -80,11 +80,11 @@ void InitMemoryForGameISO(FileLoader *fileLoader) {
return;
}
IFileSystem *fileSystem = nullptr;
IFileSystem *blockSystem = nullptr;
std::shared_ptr<IFileSystem> fileSystem;
std::shared_ptr<IFileSystem> blockSystem;
if (fileLoader->IsDirectory()) {
fileSystem = new VirtualDiscFileSystem(&pspFileSystem, fileLoader->GetPath());
fileSystem = std::shared_ptr<IFileSystem>(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<IFileSystem> iso = std::shared_ptr<IFileSystem>(new ISOFileSystem(&pspFileSystem, bd));
fileSystem = iso;
blockSystem = new ISOBlockSystem(iso);
blockSystem = std::shared_ptr<IFileSystem>(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<IFileSystem> fileSystem;
std::shared_ptr<IFileSystem> blockSystem;
if (fileLoader->IsDirectory()) {
fileSystem = new VirtualDiscFileSystem(&pspFileSystem, fileLoader->GetPath());
fileSystem = std::shared_ptr<IFileSystem>(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<IFileSystem> iso = std::shared_ptr<IFileSystem>(new ISOFileSystem(&pspFileSystem, bd));
fileSystem = iso;
blockSystem = new ISOBlockSystem(iso);
blockSystem = std::shared_ptr<IFileSystem>(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<IFileSystem> umd2 = std::shared_ptr<IFileSystem>(new ISOFileSystem(&pspFileSystem, bd));
std::shared_ptr<IFileSystem> blockSystem = std::shared_ptr<IFileSystem>(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<IFileSystem> fs = std::shared_ptr<IFileSystem>(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<IFileSystem> umd = std::shared_ptr<IFileSystem>(new BlobFileSystem(&pspFileSystem, fileLoader, "data.ppdmp"));
pspFileSystem.Mount("disc0:", umd);
PSPLoaders_Shutdown();

View file

@ -351,6 +351,7 @@ void CPU_Shutdown() {
if (coreParameter.enableSound) {
Audio_Shutdown();
}
pspFileSystem.Shutdown();
mipsr4k.Shutdown();
Memory::Shutdown();