mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	fs_user: Add a delay for each file open
This commit is contained in:
		
							parent
							
								
									d0de727a97
								
							
						
					
					
						commit
						fc7e6c9cc9
					
				
					 14 changed files with 153 additions and 11 deletions
				
			
		|  | @ -12,6 +12,7 @@ | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| #include "common/swap.h" | #include "common/swap.h" | ||||||
| #include "core/hle/result.h" | #include "core/hle/result.h" | ||||||
|  | #include "delay_generator.h" | ||||||
| 
 | 
 | ||||||
| namespace FileSys { | namespace FileSys { | ||||||
| 
 | 
 | ||||||
|  | @ -153,6 +154,27 @@ public: | ||||||
|      * @return The number of free bytes in the archive |      * @return The number of free bytes in the archive | ||||||
|      */ |      */ | ||||||
|     virtual u64 GetFreeBytes() const = 0; |     virtual u64 GetFreeBytes() const = 0; | ||||||
|  | 
 | ||||||
|  |     u64 GetReadDelayNs(std::size_t length) { | ||||||
|  |         if (delay_generator != nullptr) { | ||||||
|  |             return delay_generator->GetReadDelayNs(length); | ||||||
|  |         } | ||||||
|  |         LOG_ERROR(Service_FS, "Delay generator was not initalized. Using default"); | ||||||
|  |         delay_generator = std::make_unique<DefaultDelayGenerator>(); | ||||||
|  |         return delay_generator->GetReadDelayNs(length); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     u64 GetOpenDelayNs() { | ||||||
|  |         if (delay_generator != nullptr) { | ||||||
|  |             return delay_generator->GetOpenDelayNs(); | ||||||
|  |         } | ||||||
|  |         LOG_ERROR(Service_FS, "Delay generator was not initalized. Using default"); | ||||||
|  |         delay_generator = std::make_unique<DefaultDelayGenerator>(); | ||||||
|  |         return delay_generator->GetOpenDelayNs(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | protected: | ||||||
|  |     std::unique_ptr<DelayGenerator> delay_generator; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class ArchiveFactory : NonCopyable { | class ArchiveFactory : NonCopyable { | ||||||
|  |  | ||||||
|  | @ -59,7 +59,7 @@ private: | ||||||
| class ExtSaveDataDelayGenerator : public DelayGenerator { | class ExtSaveDataDelayGenerator : public DelayGenerator { | ||||||
| public: | public: | ||||||
|     u64 GetReadDelayNs(std::size_t length) override { |     u64 GetReadDelayNs(std::size_t length) override { | ||||||
|         // This is the delay measured for a savedate read,
 |         // This is the delay measured for a savedata read,
 | ||||||
|         // not for extsaveData
 |         // not for extsaveData
 | ||||||
|         // For now we will take that
 |         // For now we will take that
 | ||||||
|         static constexpr u64 slope(183); |         static constexpr u64 slope(183); | ||||||
|  | @ -69,6 +69,14 @@ public: | ||||||
|             std::max<u64>(static_cast<u64>(length) * slope + offset, minimum); |             std::max<u64>(static_cast<u64>(length) * slope + offset, minimum); | ||||||
|         return ipc_delay_nanoseconds; |         return ipc_delay_nanoseconds; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     u64 GetOpenDelayNs() override { | ||||||
|  |         // This is the delay measured for a savedata open,
 | ||||||
|  |         // not for extsaveData
 | ||||||
|  |         // For now we will take that
 | ||||||
|  |         static constexpr u64 IPCDelayNanoseconds(269082); | ||||||
|  |         return IPCDelayNanoseconds; | ||||||
|  |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | @ -80,7 +88,11 @@ public: | ||||||
|  */ |  */ | ||||||
| class ExtSaveDataArchive : public SaveDataArchive { | class ExtSaveDataArchive : public SaveDataArchive { | ||||||
| public: | public: | ||||||
|     explicit ExtSaveDataArchive(const std::string& mount_point) : SaveDataArchive(mount_point) {} |     explicit ExtSaveDataArchive(const std::string& mount_point, | ||||||
|  |                                 std::unique_ptr<DelayGenerator> delay_generator_) | ||||||
|  |         : SaveDataArchive(mount_point) { | ||||||
|  |         delay_generator = std::move(delay_generator_); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     std::string GetName() const override { |     std::string GetName() const override { | ||||||
|         return "ExtSaveDataArchive: " + mount_point; |         return "ExtSaveDataArchive: " + mount_point; | ||||||
|  | @ -232,7 +244,8 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(cons | ||||||
|             return ERR_NOT_FORMATTED; |             return ERR_NOT_FORMATTED; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     auto archive = std::make_unique<ExtSaveDataArchive>(fullpath); |     std::unique_ptr<DelayGenerator> delay_generator = std::make_unique<ExtSaveDataDelayGenerator>(); | ||||||
|  |     auto archive = std::make_unique<ExtSaveDataArchive>(fullpath, std::move(delay_generator)); | ||||||
|     return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); |     return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -29,6 +29,14 @@ public: | ||||||
|         u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum); |         u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum); | ||||||
|         return IPCDelayNanoseconds; |         return IPCDelayNanoseconds; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     u64 GetOpenDelayNs() override { | ||||||
|  |         // This is the delay measured on O3DS and O2DS with
 | ||||||
|  |         // https://gist.github.com/FearlessTobi/c37e143c314789251f98f2c45cd706d2
 | ||||||
|  |         // from the results the average of each length was taken.
 | ||||||
|  |         static constexpr u64 IPCDelayNanoseconds(269082); | ||||||
|  |         return IPCDelayNanoseconds; | ||||||
|  |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ResultVal<std::unique_ptr<FileBackend>> SDMCArchive::OpenFile(const Path& path, | ResultVal<std::unique_ptr<FileBackend>> SDMCArchive::OpenFile(const Path& path, | ||||||
|  | @ -378,7 +386,8 @@ bool ArchiveFactory_SDMC::Initialize() { | ||||||
| 
 | 
 | ||||||
| ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SDMC::Open(const Path& path, | ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SDMC::Open(const Path& path, | ||||||
|                                                                      u64 program_id) { |                                                                      u64 program_id) { | ||||||
|     auto archive = std::make_unique<SDMCArchive>(sdmc_directory); |     std::unique_ptr<DelayGenerator> delay_generator = std::make_unique<SDMCDelayGenerator>(); | ||||||
|  |     auto archive = std::make_unique<SDMCArchive>(sdmc_directory, std::move(delay_generator)); | ||||||
|     return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); |     return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -17,7 +17,11 @@ namespace FileSys { | ||||||
| /// Archive backend for SDMC archive
 | /// Archive backend for SDMC archive
 | ||||||
| class SDMCArchive : public ArchiveBackend { | class SDMCArchive : public ArchiveBackend { | ||||||
| public: | public: | ||||||
|     explicit SDMCArchive(const std::string& mount_point_) : mount_point(mount_point_) {} |     explicit SDMCArchive(const std::string& mount_point_, | ||||||
|  |                          std::unique_ptr<DelayGenerator> delay_generator_) | ||||||
|  |         : mount_point(mount_point_) { | ||||||
|  |         delay_generator = std::move(delay_generator_); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     std::string GetName() const override { |     std::string GetName() const override { | ||||||
|         return "SDMCArchive: " + mount_point; |         return "SDMCArchive: " + mount_point; | ||||||
|  |  | ||||||
|  | @ -15,6 +15,28 @@ | ||||||
| 
 | 
 | ||||||
| namespace FileSys { | namespace FileSys { | ||||||
| 
 | 
 | ||||||
|  | class SDMCWriteOnlyDelayGenerator : public DelayGenerator { | ||||||
|  | public: | ||||||
|  |     u64 GetReadDelayNs(std::size_t length) override { | ||||||
|  |         // This is the delay measured on O3DS and O2DS with
 | ||||||
|  |         // https://gist.github.com/B3n30/ac40eac20603f519ff106107f4ac9182
 | ||||||
|  |         // from the results the average of each length was taken.
 | ||||||
|  |         static constexpr u64 slope(183); | ||||||
|  |         static constexpr u64 offset(524879); | ||||||
|  |         static constexpr u64 minimum(631826); | ||||||
|  |         u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum); | ||||||
|  |         return IPCDelayNanoseconds; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     u64 GetOpenDelayNs() override { | ||||||
|  |         // This is the delay measured on O3DS and O2DS with
 | ||||||
|  |         // https://gist.github.com/FearlessTobi/c37e143c314789251f98f2c45cd706d2
 | ||||||
|  |         // from the results the average of each length was taken.
 | ||||||
|  |         static constexpr u64 IPCDelayNanoseconds(269082); | ||||||
|  |         return IPCDelayNanoseconds; | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| ResultVal<std::unique_ptr<FileBackend>> SDMCWriteOnlyArchive::OpenFile(const Path& path, | ResultVal<std::unique_ptr<FileBackend>> SDMCWriteOnlyArchive::OpenFile(const Path& path, | ||||||
|                                                                        const Mode& mode) const { |                                                                        const Mode& mode) const { | ||||||
|     if (mode.read_flag) { |     if (mode.read_flag) { | ||||||
|  | @ -51,7 +73,10 @@ bool ArchiveFactory_SDMCWriteOnly::Initialize() { | ||||||
| 
 | 
 | ||||||
| ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SDMCWriteOnly::Open(const Path& path, | ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SDMCWriteOnly::Open(const Path& path, | ||||||
|                                                                               u64 program_id) { |                                                                               u64 program_id) { | ||||||
|     auto archive = std::make_unique<SDMCWriteOnlyArchive>(sdmc_directory); |     std::unique_ptr<DelayGenerator> delay_generator = | ||||||
|  |         std::make_unique<SDMCWriteOnlyDelayGenerator>(); | ||||||
|  |     auto archive = | ||||||
|  |         std::make_unique<SDMCWriteOnlyArchive>(sdmc_directory, std::move(delay_generator)); | ||||||
|     return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); |     return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -19,7 +19,9 @@ namespace FileSys { | ||||||
|  */ |  */ | ||||||
| class SDMCWriteOnlyArchive : public SDMCArchive { | class SDMCWriteOnlyArchive : public SDMCArchive { | ||||||
| public: | public: | ||||||
|     explicit SDMCWriteOnlyArchive(const std::string& mount_point) : SDMCArchive(mount_point) {} |     explicit SDMCWriteOnlyArchive(const std::string& mount_point, | ||||||
|  |                                   std::unique_ptr<DelayGenerator> delay_generator_) | ||||||
|  |         : SDMCArchive(mount_point, std::move(delay_generator_)) {} | ||||||
| 
 | 
 | ||||||
|     std::string GetName() const override { |     std::string GetName() const override { | ||||||
|         return "SDMCWriteOnlyArchive: " + mount_point; |         return "SDMCWriteOnlyArchive: " + mount_point; | ||||||
|  |  | ||||||
|  | @ -19,4 +19,11 @@ u64 DefaultDelayGenerator::GetReadDelayNs(std::size_t length) { | ||||||
|     return IPCDelayNanoseconds; |     return IPCDelayNanoseconds; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | u64 DefaultDelayGenerator::GetOpenDelayNs() { | ||||||
|  |     // This is the delay measured for a romfs open.
 | ||||||
|  |     // For now we will take that as a default
 | ||||||
|  |     static constexpr u64 IPCDelayNanoseconds(9438006); | ||||||
|  |     return IPCDelayNanoseconds; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } // namespace FileSys
 | } // namespace FileSys
 | ||||||
|  |  | ||||||
|  | @ -13,6 +13,7 @@ class DelayGenerator { | ||||||
| public: | public: | ||||||
|     virtual ~DelayGenerator(); |     virtual ~DelayGenerator(); | ||||||
|     virtual u64 GetReadDelayNs(std::size_t length) = 0; |     virtual u64 GetReadDelayNs(std::size_t length) = 0; | ||||||
|  |     virtual u64 GetOpenDelayNs() = 0; | ||||||
| 
 | 
 | ||||||
|     // TODO (B3N30): Add getter for all other file/directory io operations
 |     // TODO (B3N30): Add getter for all other file/directory io operations
 | ||||||
| }; | }; | ||||||
|  | @ -20,6 +21,7 @@ public: | ||||||
| class DefaultDelayGenerator : public DelayGenerator { | class DefaultDelayGenerator : public DelayGenerator { | ||||||
| public: | public: | ||||||
|     u64 GetReadDelayNs(std::size_t length) override; |     u64 GetReadDelayNs(std::size_t length) override; | ||||||
|  |     u64 GetOpenDelayNs() override; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace FileSys
 | } // namespace FileSys
 | ||||||
|  |  | ||||||
|  | @ -55,6 +55,15 @@ public: | ||||||
|         return delay_generator->GetReadDelayNs(length); |         return delay_generator->GetReadDelayNs(length); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     u64 GetOpenDelayNs() { | ||||||
|  |         if (delay_generator != nullptr) { | ||||||
|  |             return delay_generator->GetOpenDelayNs(); | ||||||
|  |         } | ||||||
|  |         LOG_ERROR(Service_FS, "Delay generator was not initalized. Using default"); | ||||||
|  |         delay_generator = std::make_unique<DefaultDelayGenerator>(); | ||||||
|  |         return delay_generator->GetOpenDelayNs(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * Get the size of the file in bytes |      * Get the size of the file in bytes | ||||||
|      * @return Size of the file in bytes |      * @return Size of the file in bytes | ||||||
|  |  | ||||||
|  | @ -14,7 +14,11 @@ | ||||||
| 
 | 
 | ||||||
| namespace FileSys { | namespace FileSys { | ||||||
| 
 | 
 | ||||||
| IVFCArchive::IVFCArchive(std::shared_ptr<RomFSReader> file) : romfs_file(std::move(file)) {} | IVFCArchive::IVFCArchive(std::shared_ptr<RomFSReader> file, | ||||||
|  |                          std::unique_ptr<DelayGenerator> delay_generator_) | ||||||
|  |     : romfs_file(std::move(file)) { | ||||||
|  |     delay_generator = std::move(delay_generator_); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| std::string IVFCArchive::GetName() const { | std::string IVFCArchive::GetName() const { | ||||||
|     return "IVFC"; |     return "IVFC"; | ||||||
|  |  | ||||||
|  | @ -31,6 +31,13 @@ class IVFCDelayGenerator : public DelayGenerator { | ||||||
|         u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum); |         u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum); | ||||||
|         return IPCDelayNanoseconds; |         return IPCDelayNanoseconds; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     u64 GetOpenDelayNs() override { | ||||||
|  |         // This is the delay measured for a romfs open.
 | ||||||
|  |         // For now we will take that as a default
 | ||||||
|  |         static constexpr u64 IPCDelayNanoseconds(9438006); | ||||||
|  |         return IPCDelayNanoseconds; | ||||||
|  |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class RomFSDelayGenerator : public DelayGenerator { | class RomFSDelayGenerator : public DelayGenerator { | ||||||
|  | @ -45,6 +52,14 @@ public: | ||||||
|         u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum); |         u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum); | ||||||
|         return IPCDelayNanoseconds; |         return IPCDelayNanoseconds; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     u64 GetOpenDelayNs() override { | ||||||
|  |         // This is the delay measured on O3DS and O2DS with
 | ||||||
|  |         // https://gist.github.com/FearlessTobi/eb1d70619c65c7e6f02141d71e79a36e
 | ||||||
|  |         // from the results the average of each length was taken.
 | ||||||
|  |         static constexpr u64 IPCDelayNanoseconds(9438006); | ||||||
|  |         return IPCDelayNanoseconds; | ||||||
|  |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class ExeFSDelayGenerator : public DelayGenerator { | class ExeFSDelayGenerator : public DelayGenerator { | ||||||
|  | @ -59,6 +74,14 @@ public: | ||||||
|         u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum); |         u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum); | ||||||
|         return IPCDelayNanoseconds; |         return IPCDelayNanoseconds; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     u64 GetOpenDelayNs() override { | ||||||
|  |         // This is the delay measured on O3DS and O2DS with
 | ||||||
|  |         // https://gist.github.com/FearlessTobi/eb1d70619c65c7e6f02141d71e79a36e
 | ||||||
|  |         // from the results the average of each length was taken.
 | ||||||
|  |         static constexpr u64 IPCDelayNanoseconds(9438006); | ||||||
|  |         return IPCDelayNanoseconds; | ||||||
|  |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | @ -68,7 +91,8 @@ public: | ||||||
|  */ |  */ | ||||||
| class IVFCArchive : public ArchiveBackend { | class IVFCArchive : public ArchiveBackend { | ||||||
| public: | public: | ||||||
|     IVFCArchive(std::shared_ptr<RomFSReader> file); |     IVFCArchive(std::shared_ptr<RomFSReader> file, | ||||||
|  |                 std::unique_ptr<DelayGenerator> delay_generator_); | ||||||
| 
 | 
 | ||||||
|     std::string GetName() const override; |     std::string GetName() const override; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -25,6 +25,14 @@ public: | ||||||
|         u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum); |         u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum); | ||||||
|         return IPCDelayNanoseconds; |         return IPCDelayNanoseconds; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     u64 GetOpenDelayNs() override { | ||||||
|  |         // This is the delay measured on O3DS and O2DS with
 | ||||||
|  |         // https://gist.github.com/FearlessTobi/c37e143c314789251f98f2c45cd706d2
 | ||||||
|  |         // from the results the average of each length was taken.
 | ||||||
|  |         static constexpr u64 IPCDelayNanoseconds(269082); | ||||||
|  |         return IPCDelayNanoseconds; | ||||||
|  |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ResultVal<std::unique_ptr<FileBackend>> SaveDataArchive::OpenFile(const Path& path, | ResultVal<std::unique_ptr<FileBackend>> SaveDataArchive::OpenFile(const Path& path, | ||||||
|  |  | ||||||
|  | @ -234,6 +234,8 @@ public: | ||||||
|     /// Registers a new NCCH file with the SelfNCCH archive factory
 |     /// Registers a new NCCH file with the SelfNCCH archive factory
 | ||||||
|     void RegisterSelfNCCH(Loader::AppLoader& app_loader); |     void RegisterSelfNCCH(Loader::AppLoader& app_loader); | ||||||
| 
 | 
 | ||||||
|  |     ArchiveBackend* GetArchive(ArchiveHandle handle); | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     Core::System& system; |     Core::System& system; | ||||||
| 
 | 
 | ||||||
|  | @ -248,8 +250,6 @@ private: | ||||||
|     /// Register all archive types
 |     /// Register all archive types
 | ||||||
|     void RegisterArchiveTypes(); |     void RegisterArchiveTypes(); | ||||||
| 
 | 
 | ||||||
|     ArchiveBackend* GetArchive(ArchiveHandle handle); |  | ||||||
| 
 |  | ||||||
|     /**
 |     /**
 | ||||||
|      * Map of registered archives, identified by id code. Once an archive is registered here, it is |      * Map of registered archives, identified by id code. Once an archive is registered here, it is | ||||||
|      * never removed until UnregisterArchiveTypes is called. |      * never removed until UnregisterArchiveTypes is called. | ||||||
|  |  | ||||||
|  | @ -16,6 +16,7 @@ | ||||||
| #include "core/hle/ipc_helpers.h" | #include "core/hle/ipc_helpers.h" | ||||||
| #include "core/hle/kernel/client_port.h" | #include "core/hle/kernel/client_port.h" | ||||||
| #include "core/hle/kernel/client_session.h" | #include "core/hle/kernel/client_session.h" | ||||||
|  | #include "core/hle/kernel/event.h" | ||||||
| #include "core/hle/kernel/process.h" | #include "core/hle/kernel/process.h" | ||||||
| #include "core/hle/kernel/server_session.h" | #include "core/hle/kernel/server_session.h" | ||||||
| #include "core/hle/result.h" | #include "core/hle/result.h" | ||||||
|  | @ -70,6 +71,18 @@ void FS_USER::OpenFile(Kernel::HLERequestContext& ctx) { | ||||||
|         rb.PushMoveObjects<Kernel::Object>(nullptr); |         rb.PushMoveObjects<Kernel::Object>(nullptr); | ||||||
|         LOG_ERROR(Service_FS, "failed to get a handle for file {}", file_path.DebugStr()); |         LOG_ERROR(Service_FS, "failed to get a handle for file {}", file_path.DebugStr()); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     auto archive = archives.GetArchive(archive_handle); | ||||||
|  |     if (archive == nullptr) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     std::chrono::nanoseconds open_timeout_ns{archive->GetOpenDelayNs()}; | ||||||
|  |     ctx.SleepClientThread(system.Kernel().GetThreadManager().GetCurrentThread(), "fs_user::open", | ||||||
|  |                           open_timeout_ns, | ||||||
|  |                           [](Kernel::SharedPtr<Kernel::Thread> thread, | ||||||
|  |                              Kernel::HLERequestContext& ctx, Kernel::ThreadWakeupReason reason) { | ||||||
|  |                               // Nothing to do here
 | ||||||
|  |                           }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) { | void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue