From b6844bec608ed82511738e9f3911e72aeb05243a Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 16 Jun 2019 11:43:41 -0400 Subject: NVServices: Correct CtrlEventWaitSync to block the ipc until timeout. --- src/core/hle/service/nvdrv/interface.cpp | 34 ++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'src/core/hle/service/nvdrv/interface.cpp') diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp index a4cb8cb81..45912153d 100644 --- a/src/core/hle/service/nvdrv/interface.cpp +++ b/src/core/hle/service/nvdrv/interface.cpp @@ -8,6 +8,7 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/readable_event.h" +#include "core/hle/kernel/thread.h" #include "core/hle/kernel/writable_event.h" #include "core/hle/service/nvdrv/interface.h" #include "core/hle/service/nvdrv/nvdata.h" @@ -41,11 +42,36 @@ void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) { std::vector output(ctx.GetWriteBufferSize()); - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(RESULT_SUCCESS); - rb.Push(nvdrv->Ioctl(fd, command, ctx.ReadBuffer(), output)); + IoctlCtrl ctrl{}; + + u32 result = nvdrv->Ioctl(fd, command, ctx.ReadBuffer(), output, ctrl); - ctx.WriteBuffer(output); + if (!ctrl.must_delay) { + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(result); + + ctx.WriteBuffer(output); + return; + } + ctrl.fresh_call = false; + ctx.SleepClientThread( + "NVServices::DelayedResponse", ctrl.timeout, + [this, ctrl = ctrl](Kernel::SharedPtr thread, Kernel::HLERequestContext& ctx, + Kernel::ThreadWakeupReason reason) { + IPC::RequestParser rp{ctx}; + u32 fd = rp.Pop(); + u32 command = rp.Pop(); + std::vector output(ctx.GetWriteBufferSize()); + IoctlCtrl ctrl2{ctrl}; + u32 result = nvdrv->Ioctl(fd, command, ctx.ReadBuffer(), output, ctrl2); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(result); + + ctx.WriteBuffer(output); + }, + nvdrv->GetEventWriteable(ctrl.event_id)); } void NVDRV::Close(Kernel::HLERequestContext& ctx) { -- cgit v1.2.3