diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index a78a64bbf8..cd2f9fc87c 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -32,8 +32,7 @@ void SessionRequestHandler::ClientDisconnected(std::shared_ptr se connected_sessions.end()); } -std::shared_ptr HLERequestContext::SleepClientThread(std::shared_ptr thread, - const std::string& reason, +std::shared_ptr HLERequestContext::SleepClientThread(const std::string& reason, std::chrono::nanoseconds timeout, WakeupCallback&& callback) { // Put the client thread to sleep until the wait event is signaled or the timeout expires. @@ -60,7 +59,7 @@ std::shared_ptr HLERequestContext::SleepClientThread(std::shared_ptrstatus = ThreadStatus::WaitHleEvent; thread->wait_objects = {event}; - event->AddWaitingThread(thread); + event->AddWaitingThread(SharedFrom(thread)); if (timeout.count() > 0) thread->WakeAfterDelay(timeout.count()); @@ -68,8 +67,9 @@ std::shared_ptr HLERequestContext::SleepClientThread(std::shared_ptr session) - : kernel(kernel), session(std::move(session)) { +HLERequestContext::HLERequestContext(KernelSystem& kernel, std::shared_ptr session, + Thread* thread) + : kernel(kernel), session(std::move(session)), thread(thread) { cmd_buf[0] = 0; } diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 655165f8cf..6b6415832a 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -158,7 +158,7 @@ private: */ class HLERequestContext { public: - HLERequestContext(KernelSystem& kernel, std::shared_ptr session); + HLERequestContext(KernelSystem& kernel, std::shared_ptr session, Thread* thread); ~HLERequestContext(); /// Returns a pointer to the IPC command buffer for this request. @@ -180,7 +180,6 @@ public: /** * Puts the specified guest thread to sleep until the returned event is signaled or until the * specified timeout expires. - * @param thread Thread to be put to sleep. * @param reason Reason for pausing the thread, to be used for debugging purposes. * @param timeout Timeout in nanoseconds after which the thread will be awoken and the callback * invoked with a Timeout reason. @@ -189,8 +188,7 @@ public: * was called. * @returns Event that when signaled will resume the thread and call the callback function. */ - std::shared_ptr SleepClientThread(std::shared_ptr thread, - const std::string& reason, + std::shared_ptr SleepClientThread(const std::string& reason, std::chrono::nanoseconds timeout, WakeupCallback&& callback); @@ -240,6 +238,7 @@ private: KernelSystem& kernel; std::array cmd_buf; std::shared_ptr session; + Thread* thread; // TODO(yuriks): Check common usage of this and optimize size accordingly boost::container::small_vector, 8> request_handles; // The static buffers will be created when the IPC request is translated. diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 2989fa3f94..66db5500dc 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -72,7 +72,7 @@ ResultCode ServerSession::HandleSyncRequest(std::shared_ptr thread) { kernel.memory.ReadBlock(*current_process, thread->GetCommandBufferAddress(), cmd_buf.data(), cmd_buf.size() * sizeof(u32)); - Kernel::HLERequestContext context(kernel, SharedFrom(this)); + Kernel::HLERequestContext context(kernel, SharedFrom(this), thread.get()); context.PopulateFromIncomingCommandBuffer(cmd_buf.data(), *current_process); hle_handler->HandleSyncRequest(context); diff --git a/src/core/hle/service/fs/file.cpp b/src/core/hle/service/fs/file.cpp index 9efd88dd3f..fc98afc39c 100644 --- a/src/core/hle/service/fs/file.cpp +++ b/src/core/hle/service/fs/file.cpp @@ -71,8 +71,7 @@ void File::Read(Kernel::HLERequestContext& ctx) { rb.PushMappedBuffer(buffer); std::chrono::nanoseconds read_timeout_ns{backend->GetReadDelayNs(length)}; - ctx.SleepClientThread(Kernel::SharedFrom(system.Kernel().GetThreadManager().GetCurrentThread()), - "file::read", read_timeout_ns, + ctx.SleepClientThread("file::read", read_timeout_ns, [](std::shared_ptr /*thread*/, Kernel::HLERequestContext& /*ctx*/, Kernel::ThreadWakeupReason /*reason*/) { diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index ec1e1b8519..9e57fa1c4e 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -71,8 +71,7 @@ void FS_USER::OpenFile(Kernel::HLERequestContext& ctx) { LOG_ERROR(Service_FS, "failed to get a handle for file {}", file_path.DebugStr()); } - ctx.SleepClientThread(Kernel::SharedFrom(system.Kernel().GetThreadManager().GetCurrentThread()), - "fs_user::open", open_timeout_ns, + ctx.SleepClientThread("fs_user::open", open_timeout_ns, [](std::shared_ptr /*thread*/, Kernel::HLERequestContext& /*ctx*/, Kernel::ThreadWakeupReason /*reason*/) { @@ -130,8 +129,7 @@ void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) { file_path.DebugStr(), mode.hex, attributes); } - ctx.SleepClientThread(Kernel::SharedFrom(system.Kernel().GetThreadManager().GetCurrentThread()), - "fs_user::open_directly", open_timeout_ns, + ctx.SleepClientThread("fs_user::open_directly", open_timeout_ns, [](std::shared_ptr /*thread*/, Kernel::HLERequestContext& /*ctx*/, Kernel::ThreadWakeupReason /*reason*/) { diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index b64d0b3965..fe8f7635f9 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -1179,7 +1179,6 @@ void NWM_UDS::ConnectToNetwork(Kernel::HLERequestContext& ctx, u16 command_id, static constexpr std::chrono::nanoseconds UDSConnectionTimeout{300000000}; connection_event = ctx.SleepClientThread( - Kernel::SharedFrom(system.Kernel().GetThreadManager().GetCurrentThread()), "uds::ConnectToNetwork", UDSConnectionTimeout, [command_id](std::shared_ptr thread, Kernel::HLERequestContext& ctx, Kernel::ThreadWakeupReason reason) { diff --git a/src/core/hle/service/sm/srv.cpp b/src/core/hle/service/sm/srv.cpp index ab6585b6b5..396bd3559e 100644 --- a/src/core/hle/service/sm/srv.cpp +++ b/src/core/hle/service/sm/srv.cpp @@ -127,9 +127,8 @@ void SRV::GetServiceHandle(Kernel::HLERequestContext& ctx) { if (client_port.Failed()) { if (wait_until_available && client_port.Code() == ERR_SERVICE_NOT_REGISTERED) { LOG_INFO(Service_SRV, "called service={} delayed", name); - std::shared_ptr get_service_handle_event = ctx.SleepClientThread( - Kernel::SharedFrom(system.Kernel().GetThreadManager().GetCurrentThread()), - "GetServiceHandle", std::chrono::nanoseconds(-1), get_handle); + std::shared_ptr get_service_handle_event = + ctx.SleepClientThread("GetServiceHandle", std::chrono::nanoseconds(-1), get_handle); get_service_handle_delayed_map[name] = std::move(get_service_handle_event); return; } else { diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index 455f50883a..2dd3a0424a 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -25,7 +25,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel Memory::MemorySystem memory; Kernel::KernelSystem kernel(memory, timing, [] {}, 0); auto session = std::get>(kernel.CreateSessionPair()); - HLERequestContext context(kernel, std::move(session)); + HLERequestContext context(kernel, std::move(session), nullptr); auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); @@ -237,7 +237,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { Memory::MemorySystem memory; Kernel::KernelSystem kernel(memory, timing, [] {}, 0); auto session = std::get>(kernel.CreateSessionPair()); - HLERequestContext context(kernel, std::move(session)); + HLERequestContext context(kernel, std::move(session), nullptr); auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); auto* input = context.CommandBuffer();