mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #14638 from hrydgard/metafilesystem-cleanup
Cleanup the ownership model in MetaFileSystem.
This commit is contained in:
commit
e9f19e133b
6 changed files with 73 additions and 89 deletions
|
@ -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_;
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -351,6 +351,7 @@ void CPU_Shutdown() {
|
|||
if (coreParameter.enableSound) {
|
||||
Audio_Shutdown();
|
||||
}
|
||||
|
||||
pspFileSystem.Shutdown();
|
||||
mipsr4k.Shutdown();
|
||||
Memory::Shutdown();
|
||||
|
|
Loading…
Add table
Reference in a new issue