mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-10-23 18:30:24 +02:00
[fs] Allow real VFS files to be replaced while open
Add a Windows share-delete file open mode and use it for cached real VFS files. Close cached references before create, move, and delete so guest-side self-update flows can rename or replace files that Eden previously opened. Also preserve Android real VFS full paths so homebrew path derivation does not lose the original file path.
This commit is contained in:
parent
8ab9521cea
commit
c87f6202d3
4 changed files with 112 additions and 10 deletions
|
|
@ -12,7 +12,6 @@
|
|||
#include "common/fs/file.h"
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include "common/logging.h"
|
||||
#include "core/file_sys/vfs/vfs.h"
|
||||
#include "core/file_sys/vfs/vfs_real.h"
|
||||
|
||||
|
|
@ -124,6 +123,7 @@ VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, OpenMode perms
|
|||
const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
|
||||
{
|
||||
std::scoped_lock lk{list_lock};
|
||||
CloseCachedFileReferenceLocked(path);
|
||||
cache.erase(path);
|
||||
}
|
||||
|
||||
|
|
@ -157,6 +157,8 @@ VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_
|
|||
const auto new_path = FS::SanitizePath(new_path_, FS::DirectorySeparator::PlatformDefault);
|
||||
{
|
||||
std::scoped_lock lk{list_lock};
|
||||
CloseCachedFileReferenceLocked(old_path);
|
||||
CloseCachedFileReferenceLocked(new_path);
|
||||
cache.erase(old_path);
|
||||
cache.erase(new_path);
|
||||
}
|
||||
|
|
@ -170,6 +172,7 @@ bool RealVfsFilesystem::DeleteFile(std::string_view path_) {
|
|||
const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
|
||||
{
|
||||
std::scoped_lock lk{list_lock};
|
||||
CloseCachedFileReferenceLocked(path);
|
||||
cache.erase(path);
|
||||
}
|
||||
return FS::RemoveFile(path);
|
||||
|
|
@ -222,8 +225,8 @@ std::unique_lock<std::mutex> RealVfsFilesystem::RefreshReference(const std::stri
|
|||
if (!reference.file) {
|
||||
this->EvictSingleReferenceLocked();
|
||||
|
||||
reference.file =
|
||||
FS::FileOpen(path, ModeFlagsToFileAccessMode(perms), FS::FileType::BinaryFile);
|
||||
reference.file = FS::FileOpen(path, ModeFlagsToFileAccessMode(perms),
|
||||
FS::FileType::BinaryFile, FS::FileShareFlag::ShareReadWriteDelete);
|
||||
if (reference.file) {
|
||||
num_open_files++;
|
||||
}
|
||||
|
|
@ -297,15 +300,50 @@ RealVfsFile::~RealVfsFile() {
|
|||
base.DropReference(std::move(reference));
|
||||
}
|
||||
|
||||
void RealVfsFilesystem::CloseCachedFileReferenceLocked(const std::string& path) {
|
||||
const auto it = cache.find(path);
|
||||
if (it == cache.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto cached_file = it->second.lock();
|
||||
if (!cached_file) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* real_file = static_cast<RealVfsFile*>(cached_file.get());
|
||||
auto& reference = real_file->reference;
|
||||
if (!reference || !reference->file) {
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveReferenceFromListLocked(*reference);
|
||||
reference->file.reset();
|
||||
num_open_files--;
|
||||
InsertReferenceIntoListLocked(*reference);
|
||||
}
|
||||
|
||||
std::string RealVfsFile::GetName() const {
|
||||
#ifdef __ANDROID__
|
||||
if (path[0] != '/') {
|
||||
if (!path.empty() && path[0] != '/') {
|
||||
return FS::Android::GetFilename(path);
|
||||
}
|
||||
#endif
|
||||
return path_components.empty() ? "" : std::string(path_components.back());
|
||||
}
|
||||
|
||||
std::string RealVfsFile::GetFullPath() const {
|
||||
#ifdef __ANDROID__
|
||||
if (!path.empty() && path[0] != '/') {
|
||||
auto out = path;
|
||||
std::replace(out.begin(), out.end(), '\\', '/');
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
return VfsFile::GetFullPath();
|
||||
}
|
||||
|
||||
std::size_t RealVfsFile::GetSize() const {
|
||||
if (size) {
|
||||
return *size;
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ private:
|
|||
std::unique_lock<std::mutex> RefreshReference(const std::string& path, OpenMode perms,
|
||||
FileReference& reference);
|
||||
void DropReference(std::unique_ptr<FileReference>&& reference);
|
||||
void CloseCachedFileReferenceLocked(const std::string& path);
|
||||
|
||||
private:
|
||||
friend class RealVfsDirectory;
|
||||
|
|
@ -85,6 +86,7 @@ public:
|
|||
~RealVfsFile() override;
|
||||
|
||||
std::string GetName() const override;
|
||||
std::string GetFullPath() const override;
|
||||
std::size_t GetSize() const override;
|
||||
bool Resize(std::size_t new_size) override;
|
||||
VirtualDir GetContainingDirectory() const override;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue