summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel/hle_ipc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/hle_ipc.cpp')
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index aae14f09e..293756790 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -7,6 +7,7 @@
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/event.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/kernel/kernel.h"
@@ -26,6 +27,32 @@ void SessionRequestHandler::ClientDisconnected(SharedPtr<ServerSession> server_s
boost::range::remove_erase(connected_sessions, server_session);
}
+SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread,
+ const std::string& reason, u64 timeout,
+ WakeupCallback&& callback) {
+
+ // Put the client thread to sleep until the wait event is signaled or the timeout expires.
+ thread->wakeup_callback =
+ [context = *this, callback](ThreadWakeupReason reason, SharedPtr<Thread> thread,
+ SharedPtr<WaitObject> object, size_t index) mutable -> bool {
+ ASSERT(thread->status == THREADSTATUS_WAIT_HLE_EVENT);
+ callback(thread, context, reason);
+ context.WriteToOutgoingCommandBuffer(*thread);
+ return true;
+ };
+
+ auto event = Kernel::Event::Create(Kernel::ResetType::OneShot, "HLE Pause Event: " + reason);
+ thread->status = THREADSTATUS_WAIT_HLE_EVENT;
+ thread->wait_objects = {event};
+ event->AddWaitingThread(thread);
+
+ if (timeout > 0) {
+ thread->WakeAfterDelay(timeout);
+ }
+
+ return event;
+}
+
HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session)
: server_session(std::move(server_session)) {
cmd_buf[0] = 0;