diff options
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.cpp | 27 | ||||
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.h | 20 |
2 files changed, 47 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 @@ | |||
| 7 | #include "common/common_funcs.h" | 7 | #include "common/common_funcs.h" |
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | #include "core/hle/ipc_helpers.h" | 9 | #include "core/hle/ipc_helpers.h" |
| 10 | #include "core/hle/kernel/event.h" | ||
| 10 | #include "core/hle/kernel/handle_table.h" | 11 | #include "core/hle/kernel/handle_table.h" |
| 11 | #include "core/hle/kernel/hle_ipc.h" | 12 | #include "core/hle/kernel/hle_ipc.h" |
| 12 | #include "core/hle/kernel/kernel.h" | 13 | #include "core/hle/kernel/kernel.h" |
| @@ -26,6 +27,32 @@ void SessionRequestHandler::ClientDisconnected(SharedPtr<ServerSession> server_s | |||
| 26 | boost::range::remove_erase(connected_sessions, server_session); | 27 | boost::range::remove_erase(connected_sessions, server_session); |
| 27 | } | 28 | } |
| 28 | 29 | ||
| 30 | SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread, | ||
| 31 | const std::string& reason, u64 timeout, | ||
| 32 | WakeupCallback&& callback) { | ||
| 33 | |||
| 34 | // Put the client thread to sleep until the wait event is signaled or the timeout expires. | ||
| 35 | thread->wakeup_callback = | ||
| 36 | [context = *this, callback](ThreadWakeupReason reason, SharedPtr<Thread> thread, | ||
| 37 | SharedPtr<WaitObject> object, size_t index) mutable -> bool { | ||
| 38 | ASSERT(thread->status == THREADSTATUS_WAIT_HLE_EVENT); | ||
| 39 | callback(thread, context, reason); | ||
| 40 | context.WriteToOutgoingCommandBuffer(*thread); | ||
| 41 | return true; | ||
| 42 | }; | ||
| 43 | |||
| 44 | auto event = Kernel::Event::Create(Kernel::ResetType::OneShot, "HLE Pause Event: " + reason); | ||
| 45 | thread->status = THREADSTATUS_WAIT_HLE_EVENT; | ||
| 46 | thread->wait_objects = {event}; | ||
| 47 | event->AddWaitingThread(thread); | ||
| 48 | |||
| 49 | if (timeout > 0) { | ||
| 50 | thread->WakeAfterDelay(timeout); | ||
| 51 | } | ||
| 52 | |||
| 53 | return event; | ||
| 54 | } | ||
| 55 | |||
| 29 | HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session) | 56 | HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session) |
| 30 | : server_session(std::move(server_session)) { | 57 | : server_session(std::move(server_session)) { |
| 31 | cmd_buf[0] = 0; | 58 | cmd_buf[0] = 0; |
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index b5cc0d0af..8b35da4c9 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <memory> | 8 | #include <memory> |
| 9 | #include <string> | ||
| 9 | #include <vector> | 10 | #include <vector> |
| 10 | #include <boost/container/small_vector.hpp> | 11 | #include <boost/container/small_vector.hpp> |
| 11 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| @@ -25,6 +26,7 @@ class Domain; | |||
| 25 | class HandleTable; | 26 | class HandleTable; |
| 26 | class HLERequestContext; | 27 | class HLERequestContext; |
| 27 | class Process; | 28 | class Process; |
| 29 | class Event; | ||
| 28 | 30 | ||
| 29 | /** | 31 | /** |
| 30 | * Interface implemented by HLE Session handlers. | 32 | * Interface implemented by HLE Session handlers. |
| @@ -103,6 +105,24 @@ public: | |||
| 103 | return server_session; | 105 | return server_session; |
| 104 | } | 106 | } |
| 105 | 107 | ||
| 108 | using WakeupCallback = std::function<void(SharedPtr<Thread> thread, HLERequestContext& context, | ||
| 109 | ThreadWakeupReason reason)>; | ||
| 110 | |||
| 111 | /** | ||
| 112 | * Puts the specified guest thread to sleep until the returned event is signaled or until the | ||
| 113 | * specified timeout expires. | ||
| 114 | * @param thread Thread to be put to sleep. | ||
| 115 | * @param reason Reason for pausing the thread, to be used for debugging purposes. | ||
| 116 | * @param timeout Timeout in nanoseconds after which the thread will be awoken and the callback | ||
| 117 | * invoked with a Timeout reason. | ||
| 118 | * @param callback Callback to be invoked when the thread is resumed. This callback must write | ||
| 119 | * the entire command response once again, regardless of the state of it before this function | ||
| 120 | * was called. | ||
| 121 | * @returns Event that when signaled will resume the thread and call the callback function. | ||
| 122 | */ | ||
| 123 | SharedPtr<Event> SleepClientThread(SharedPtr<Thread> thread, const std::string& reason, | ||
| 124 | u64 timeout, WakeupCallback&& callback); | ||
| 125 | |||
| 106 | void ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming); | 126 | void ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming); |
| 107 | 127 | ||
| 108 | /// Populates this context with data from the requesting process/thread. | 128 | /// Populates this context with data from the requesting process/thread. |