|
|
@@ -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;
|