diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 1e9ee2c60..259ece84a 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -11,8 +11,8 @@ #include "common/bit_field.h" #include "common/common_types.h" #include "common/swap.h" +#include "core/file_sys/delay_generator.h" #include "core/hle/result.h" -#include "delay_generator.h" namespace FileSys { @@ -155,15 +155,6 @@ public: */ 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(); - return delay_generator->GetReadDelayNs(length); - } - u64 GetOpenDelayNs() { if (delay_generator != nullptr) { return delay_generator->GetOpenDelayNs(); diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 184c319f0..6e179978b 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -77,19 +77,21 @@ ResultCode ArchiveManager::RegisterArchiveType(std::unique_ptr> ArchiveManager::OpenFileFromArchive(ArchiveHandle archive_handle, - const FileSys::Path& path, - const FileSys::Mode mode) { +std::tuple>, std::chrono::nanoseconds> +ArchiveManager::OpenFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path, + const FileSys::Mode mode) { ArchiveBackend* archive = GetArchive(archive_handle); if (archive == nullptr) - return FileSys::ERR_INVALID_ARCHIVE_HANDLE; + return std::make_tuple(FileSys::ERR_INVALID_ARCHIVE_HANDLE, + static_cast(0)); + std::chrono::nanoseconds open_timeout_ns{archive->GetOpenDelayNs()}; auto backend = archive->OpenFile(path, mode); if (backend.Failed()) - return backend.Code(); + return std::make_tuple(backend.Code(), open_timeout_ns); auto file = std::shared_ptr(new File(system, std::move(backend).Unwrap(), path)); - return MakeResult>(std::move(file)); + return std::make_tuple(MakeResult>(std::move(file)), open_timeout_ns); } ResultCode ArchiveManager::DeleteFileFromArchive(ArchiveHandle archive_handle, diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index 45f6b7eec..862e74980 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -77,11 +77,10 @@ public: * @param archive_handle Handle to an open Archive object * @param path Path to the File inside of the Archive * @param mode Mode under which to open the File - * @return The opened File object + * @return Tuple of the opened File object and the open delay */ - ResultVal> OpenFileFromArchive(ArchiveHandle archive_handle, - const FileSys::Path& path, - const FileSys::Mode mode); + std::tuple>, std::chrono::nanoseconds> OpenFileFromArchive( + ArchiveHandle archive_handle, const FileSys::Path& path, const FileSys::Mode mode); /** * Delete a File from an Archive @@ -234,8 +233,6 @@ public: /// Registers a new NCCH file with the SelfNCCH archive factory void RegisterSelfNCCH(Loader::AppLoader& app_loader); - ArchiveBackend* GetArchive(ArchiveHandle handle); - private: Core::System& system; @@ -250,6 +247,8 @@ private: /// Register all archive types void RegisterArchiveTypes(); + ArchiveBackend* GetArchive(ArchiveHandle handle); + /** * Map of registered archives, identified by id code. Once an archive is registered here, it is * never removed until UnregisterArchiveTypes is called. diff --git a/src/core/hle/service/fs/file.cpp b/src/core/hle/service/fs/file.cpp index d4beda2c4..0edd93644 100644 --- a/src/core/hle/service/fs/file.cpp +++ b/src/core/hle/service/fs/file.cpp @@ -71,12 +71,12 @@ void File::Read(Kernel::HLERequestContext& ctx) { rb.PushMappedBuffer(buffer); std::chrono::nanoseconds read_timeout_ns{backend->GetReadDelayNs(length)}; - ctx.SleepClientThread(system.Kernel().GetThreadManager().GetCurrentThread(), "file::read", - read_timeout_ns, - [](Kernel::SharedPtr thread, - Kernel::HLERequestContext& ctx, Kernel::ThreadWakeupReason reason) { - // Nothing to do here - }); + ctx.SleepClientThread( + system.Kernel().GetThreadManager().GetCurrentThread(), "file::read", read_timeout_ns, + [](Kernel::SharedPtr /*thread*/, Kernel::HLERequestContext& /*ctx*/, + Kernel::ThreadWakeupReason /*reason*/) { + // Nothing to do here + }); } void File::Write(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index c4b8843c3..51bc18374 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -60,7 +60,7 @@ void FS_USER::OpenFile(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_FS, "path={}, mode={} attrs={}", file_path.DebugStr(), mode.hex, attributes); - ResultVal> file_res = + const auto [file_res, open_timeout_ns] = archives.OpenFileFromArchive(archive_handle, file_path, mode); IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); rb.Push(file_res.Code()); @@ -72,17 +72,12 @@ void FS_USER::OpenFile(Kernel::HLERequestContext& ctx) { 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 thread, - Kernel::HLERequestContext& ctx, Kernel::ThreadWakeupReason reason) { - // Nothing to do here - }); + ctx.SleepClientThread( + system.Kernel().GetThreadManager().GetCurrentThread(), "fs_user::open", open_timeout_ns, + [](Kernel::SharedPtr /*thread*/, Kernel::HLERequestContext& /*ctx*/, + Kernel::ThreadWakeupReason /*reason*/) { + // Nothing to do here + }); } void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) { @@ -123,7 +118,7 @@ void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) { } SCOPE_EXIT({ archives.CloseArchive(*archive_handle); }); - ResultVal> file_res = + const auto [file_res, open_timeout_ns] = archives.OpenFileFromArchive(*archive_handle, file_path, mode); rb.Push(file_res.Code()); if (file_res.Succeeded()) { @@ -134,6 +129,14 @@ void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) { LOG_ERROR(Service_FS, "failed to get a handle for file {} mode={} attributes={}", file_path.DebugStr(), mode.hex, attributes); } + + ctx.SleepClientThread(system.Kernel().GetThreadManager().GetCurrentThread(), + "fs_user::open_directly", open_timeout_ns, + [](Kernel::SharedPtr /*thread*/, + Kernel::HLERequestContext& /*ctx*/, + Kernel::ThreadWakeupReason /*reason*/) { + // Nothing to do here + }); } void FS_USER::DeleteFile(Kernel::HLERequestContext& ctx) {