File xenia_PR2123.patch of Package xenia

From e99a74685af3872d09efb99dda2e99c96740e628 Mon Sep 17 00:00:00 2001
From: Gliniak <Gliniak93@gmail.com>
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 791d791016..4fec1d2c5f 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 d680dffe52..1fcc705c2f 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_;
 };
 
openSUSE Build Service is sponsored by