Browse Source

don't hold handle all the time to the file

fs_external_dlcupdates
unknown 2 months ago
committed by crueter
parent
commit
336b9a806f
  1. 47
      src/core/file_sys/vfs/vfs_real.cpp
  2. 1
      src/core/file_sys/vfs/vfs_real.h

47
src/core/file_sys/vfs/vfs_real.cpp

@ -211,7 +211,8 @@ std::unique_lock<std::mutex> RealVfsFilesystem::RefreshReference(const std::stri
this->EvictSingleReferenceLocked();
reference.file =
FS::FileOpen(path, ModeFlagsToFileAccessMode(perms), FS::FileType::BinaryFile);
FS::FileOpen(path, ModeFlagsToFileAccessMode(perms), FS::FileType::BinaryFile,
FS::FileShareFlag::ShareReadWrite);
if (reference.file) {
num_open_files++;
}
@ -236,6 +237,19 @@ void RealVfsFilesystem::DropReference(std::unique_ptr<FileReference>&& reference
}
}
void RealVfsFilesystem::CloseReference(FileReference& reference) {
std::scoped_lock lk{list_lock};
if (!reference.file) {
return;
}
this->RemoveReferenceFromListLocked(reference);
reference.file.reset();
if (num_open_files > 0) {
num_open_files--;
}
this->InsertReferenceIntoListLocked(reference);
}
void RealVfsFilesystem::EvictSingleReferenceLocked() {
if (num_open_files < MaxOpenFiles || open_references.empty()) {
return;
@ -304,13 +318,19 @@ std::size_t RealVfsFile::GetSize() const {
return *size;
}
auto lk = base.RefreshReference(path, perms, *reference);
return reference->file ? reference->file->GetSize() : 0;
const auto result = reference->file ? reference->file->GetSize() : 0;
lk.unlock();
base.CloseReference(*reference);
return result;
}
bool RealVfsFile::Resize(std::size_t new_size) {
size.reset();
auto lk = base.RefreshReference(path, perms, *reference);
return reference->file ? reference->file->SetSize(new_size) : false;
const bool ok = reference->file ? reference->file->SetSize(new_size) : false;
lk.unlock();
base.CloseReference(*reference);
return ok;
}
VirtualDir RealVfsFile::GetContainingDirectory() const {
@ -326,20 +346,37 @@ bool RealVfsFile::IsReadable() const {
}
std::size_t RealVfsFile::Read(u8* data, std::size_t length, std::size_t offset) const {
if (length != 0 && data == nullptr) {
LOG_ERROR(Common_Filesystem,
"RealVfsFile::Read called with null buffer (len={}, off={}, path={})",
length, offset, path);
return 0;
}
auto lk = base.RefreshReference(path, perms, *reference);
if (!reference->file || !reference->file->Seek(static_cast<s64>(offset))) {
lk.unlock();
base.CloseReference(*reference);
return 0;
}
return reference->file->ReadSpan(std::span{data, length});
const auto read = reference->file->ReadSpan(std::span{data, length});
lk.unlock();
base.CloseReference(*reference);
return read;
}
std::size_t RealVfsFile::Write(const u8* data, std::size_t length, std::size_t offset) {
size.reset();
auto lk = base.RefreshReference(path, perms, *reference);
if (!reference->file || !reference->file->Seek(static_cast<s64>(offset))) {
lk.unlock();
base.CloseReference(*reference);
return 0;
}
return reference->file->WriteSpan(std::span{data, length});
const auto written = reference->file->WriteSpan(std::span{data, length});
lk.unlock();
base.CloseReference(*reference);
return written;
}
bool RealVfsFile::Rename(std::string_view name) {

1
src/core/file_sys/vfs/vfs_real.h

@ -58,6 +58,7 @@ private:
std::unique_lock<std::mutex> RefreshReference(const std::string& path, OpenMode perms,
FileReference& reference);
void DropReference(std::unique_ptr<FileReference>&& reference);
void CloseReference(FileReference& reference);
private:
friend class RealVfsDirectory;

Loading…
Cancel
Save