Merge pull request #4396 from FearlessTobi/open-delays

fs_user: Add a delay for each file open
This commit is contained in:
Weiyi Wang 2019-03-23 12:21:12 -04:00 committed by GitHub
commit 21bda754b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 164 additions and 27 deletions

View file

@ -77,19 +77,21 @@ ResultCode ArchiveManager::RegisterArchiveType(std::unique_ptr<FileSys::ArchiveF
return RESULT_SUCCESS;
}
ResultVal<std::shared_ptr<File>> ArchiveManager::OpenFileFromArchive(ArchiveHandle archive_handle,
const FileSys::Path& path,
const FileSys::Mode mode) {
std::tuple<ResultVal<std::shared_ptr<File>>, 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<std::chrono::nanoseconds>(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<File>(new File(system, std::move(backend).Unwrap(), path));
return MakeResult<std::shared_ptr<File>>(std::move(file));
return std::make_tuple(MakeResult<std::shared_ptr<File>>(std::move(file)), open_timeout_ns);
}
ResultCode ArchiveManager::DeleteFileFromArchive(ArchiveHandle archive_handle,

View file

@ -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<std::shared_ptr<File>> OpenFileFromArchive(ArchiveHandle archive_handle,
const FileSys::Path& path,
const FileSys::Mode mode);
std::tuple<ResultVal<std::shared_ptr<File>>, std::chrono::nanoseconds> OpenFileFromArchive(
ArchiveHandle archive_handle, const FileSys::Path& path, const FileSys::Mode mode);
/**
* Delete a File from an Archive

View file

@ -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<Kernel::Thread> thread,
Kernel::HLERequestContext& ctx, Kernel::ThreadWakeupReason reason) {
// Nothing to do here
});
ctx.SleepClientThread(
system.Kernel().GetThreadManager().GetCurrentThread(), "file::read", read_timeout_ns,
[](Kernel::SharedPtr<Kernel::Thread> /*thread*/, Kernel::HLERequestContext& /*ctx*/,
Kernel::ThreadWakeupReason /*reason*/) {
// Nothing to do here
});
}
void File::Write(Kernel::HLERequestContext& ctx) {

View file

@ -16,6 +16,7 @@
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/client_session.h"
#include "core/hle/kernel/event.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/server_session.h"
#include "core/hle/result.h"
@ -59,7 +60,7 @@ void FS_USER::OpenFile(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_FS, "path={}, mode={} attrs={}", file_path.DebugStr(), mode.hex, attributes);
ResultVal<std::shared_ptr<File>> 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());
@ -70,6 +71,13 @@ void FS_USER::OpenFile(Kernel::HLERequestContext& ctx) {
rb.PushMoveObjects<Kernel::Object>(nullptr);
LOG_ERROR(Service_FS, "failed to get a handle for file {}", file_path.DebugStr());
}
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) {
@ -110,7 +118,7 @@ void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) {
}
SCOPE_EXIT({ archives.CloseArchive(*archive_handle); });
ResultVal<std::shared_ptr<File>> 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()) {
@ -121,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<Kernel::Thread> /*thread*/,
Kernel::HLERequestContext& /*ctx*/,
Kernel::ThreadWakeupReason /*reason*/) {
// Nothing to do here
});
}
void FS_USER::DeleteFile(Kernel::HLERequestContext& ctx) {