mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2024-07-04 23:31:19 +01:00
hle_ipc: Add SleepClientThread to block current thread within HLE routines.
This commit is contained in:
parent
2faa83ca13
commit
c86af6939c
2 changed files with 47 additions and 0 deletions
|
@ -7,6 +7,7 @@
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
|
#include "core/hle/kernel/event.h"
|
||||||
#include "core/hle/kernel/handle_table.h"
|
#include "core/hle/kernel/handle_table.h"
|
||||||
#include "core/hle/kernel/hle_ipc.h"
|
#include "core/hle/kernel/hle_ipc.h"
|
||||||
#include "core/hle/kernel/kernel.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);
|
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)
|
HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session)
|
||||||
: server_session(std::move(server_session)) {
|
: server_session(std::move(server_session)) {
|
||||||
cmd_buf[0] = 0;
|
cmd_buf[0] = 0;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
@ -25,6 +26,7 @@ class Domain;
|
||||||
class HandleTable;
|
class HandleTable;
|
||||||
class HLERequestContext;
|
class HLERequestContext;
|
||||||
class Process;
|
class Process;
|
||||||
|
class Event;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface implemented by HLE Session handlers.
|
* Interface implemented by HLE Session handlers.
|
||||||
|
@ -103,6 +105,24 @@ public:
|
||||||
return server_session;
|
return server_session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using WakeupCallback = std::function<void(SharedPtr<Thread> thread, HLERequestContext& context,
|
||||||
|
ThreadWakeupReason reason)>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
* @param callback Callback to be invoked when the thread is resumed. This callback must write
|
||||||
|
* the entire command response once again, regardless of the state of it before this function
|
||||||
|
* was called.
|
||||||
|
* @returns Event that when signaled will resume the thread and call the callback function.
|
||||||
|
*/
|
||||||
|
SharedPtr<Event> SleepClientThread(SharedPtr<Thread> thread, const std::string& reason,
|
||||||
|
u64 timeout, WakeupCallback&& callback);
|
||||||
|
|
||||||
void ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming);
|
void ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming);
|
||||||
|
|
||||||
/// Populates this context with data from the requesting process/thread.
|
/// Populates this context with data from the requesting process/thread.
|
||||||
|
|
Loading…
Reference in a new issue