From e99a74685af3872d09efb99dda2e99c96740e628 Mon Sep 17 00:00:00 2001 From: Gliniak Date: Sun, 5 Feb 2023 12:11:57 +0100 Subject: [PATCH] [STFS] Add critical section to file reading Seems like reading same file concurrently from many threads can cause situation when random thread receives incorrect data --- src/xenia/vfs/devices/stfs_container_file.cc | 13 ++++++++----- src/xenia/vfs/devices/stfs_container_file.h | 2 ++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/xenia/vfs/devices/stfs_container_file.cc b/src/xenia/vfs/devices/stfs_container_file.cc index 791d7910168..4fec1d2c5f7 100644 --- a/src/xenia/vfs/devices/stfs_container_file.cc +++ b/src/xenia/vfs/devices/stfs_container_file.cc @@ -52,12 +52,15 @@ X_STATUS StfsContainerFile::ReadSync(void* buffer, size_t buffer_length, size_t read_length = std::min(record.length - read_offset, remaining_length); - auto& file = entry_->files()->at(record.file); - xe::filesystem::Seek(file, record.offset + read_offset, SEEK_SET); - auto num_read = fread(p, 1, read_length, file); + auto global_lock = global_critical_region_.Acquire(); + { + auto& file = entry_->files()->at(record.file); + xe::filesystem::Seek(file, record.offset + read_offset, SEEK_SET); + auto num_read = fread(p, 1, read_length, file); - *out_bytes_read += num_read; - p += num_read; + *out_bytes_read += num_read; + p += num_read; + } src_offset += record.length; remaining_length -= read_length; if (remaining_length == 0) { diff --git a/src/xenia/vfs/devices/stfs_container_file.h b/src/xenia/vfs/devices/stfs_container_file.h index d680dffe526..1fcc705c2f4 100644 --- a/src/xenia/vfs/devices/stfs_container_file.h +++ b/src/xenia/vfs/devices/stfs_container_file.h @@ -10,6 +10,7 @@ #ifndef XENIA_VFS_DEVICES_STFS_CONTAINER_FILE_H_ #define XENIA_VFS_DEVICES_STFS_CONTAINER_FILE_H_ +#include "xenia/base/mutex.h" #include "xenia/vfs/file.h" #include "xenia/xbox.h" @@ -35,6 +36,7 @@ class StfsContainerFile : public File { X_STATUS SetLength(size_t length) override { return X_STATUS_ACCESS_DENIED; } private: + xe::global_critical_region global_critical_region_; StfsContainerEntry* entry_; };