diff --git a/src/core/hle/ipc.h b/src/core/hle/ipc.h index 0dcaede678..3a1c080af0 100644 --- a/src/core/hle/ipc.h +++ b/src/core/hle/ipc.h @@ -14,6 +14,8 @@ namespace IPC { /// Size of the command buffer area, in 32-bit words. constexpr size_t COMMAND_BUFFER_LENGTH = 0x100 / sizeof(u32); +/// Maximum number of static buffers per thread +constexpr size_t MAX_STATIC_BUFFERS = 16; // These errors are commonly returned by invalid IPC translations, so alias them here for // convenience. // TODO(yuriks): These will probably go away once translation is implemented inside the kernel. diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 953a7604f8..be855adc28 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -26,15 +26,23 @@ void SessionRequestHandler::ClientDisconnected(SharedPtr server_s boost::range::remove_erase(connected_sessions, server_session); } +HLERequestContext::HLERequestContext(SharedPtr server_session) + : server_session(std::move(server_session)) { + cmd_buf[0] = 0; +} + +HLERequestContext::~HLERequestContext() = default; + SharedPtr HLERequestContext::SleepClientThread(SharedPtr 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, + thread->wakeup_callback = [context = this, callback](ThreadWakeupReason reason, SharedPtr thread, - SharedPtr object) mutable { + SharedPtr object, + size_t index) mutable -> bool { ASSERT(thread->status == THREADSTATUS_WAIT_HLE_EVENT); - callback(thread, context, reason); + callback(thread, *context, reason); auto& process = thread->owner_process; // We must copy the entire command buffer *plus* the entire static buffers area, since @@ -43,7 +51,7 @@ SharedPtr HLERequestContext::SleepClientThread(SharedPtr thread, std::array cmd_buff; Memory::ReadBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(), cmd_buff.size() * sizeof(u32)); - context.WriteToOutgoingCommandBuffer(cmd_buff.data(), *process, Kernel::g_handle_table); + context->WriteToOutgoingCommandBuffer(cmd_buff.data(), *process, Kernel::g_handle_table); // Copy the translated command buffer back into the thread's command buffer area. Memory::WriteBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(), cmd_buff.size() * sizeof(u32)); @@ -60,13 +68,6 @@ SharedPtr HLERequestContext::SleepClientThread(SharedPtr thread, return event; } -HLERequestContext::HLERequestContext(SharedPtr server_session) - : server_session(std::move(server_session)) { - cmd_buf[0] = 0; -} - -HLERequestContext::~HLERequestContext() = default; - void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) { IPC::RequestParser rp(src_cmdbuf); command_header = std::make_unique(rp.PopRaw()); diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index cdd8c5e1a4..c4503cd1da 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -14,7 +14,7 @@ #include "core/hle/ipc.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/server_session.h" - +#include "core/hle/kernel/thread.h" namespace Service { class ServiceFrameworkBase; } @@ -101,13 +101,12 @@ public: * Returns the session through which this request was made. This can be used as a map key to * access per-client data on services. */ - const SharedPtr& Session() const { + SharedPtr Session() const { return server_session; } using WakeupCallback = std::function thread, HLERequestContext& context, ThreadWakeupReason reason)>; - /* * Puts the specified guest thread to sleep until the returned event is signaled or until the * specified timeout expires. diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 0a1ada27dc..2c7581f1c7 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -39,6 +39,7 @@ enum ThreadStatus { THREADSTATUS_RUNNING, ///< Currently running THREADSTATUS_READY, ///< Ready to run THREADSTATUS_WAIT_ARB, ///< Waiting on an address arbiter + THREADSTATUS_WAIT_HLE_EVENT, ///< Waiting for hle event to finish THREADSTATUS_WAIT_SLEEP, ///< Waiting due to a SleepThread SVC THREADSTATUS_WAIT_SYNCH_ANY, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false THREADSTATUS_WAIT_SYNCH_ALL, ///< Waiting due to WaitSynchronizationN with wait_all = true diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index e5252abdc3..5802b98559 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -187,7 +187,8 @@ void GMainWindow::InitializeHotkeys() { RegisterHotkey("Main Window", "Load File", QKeySequence::Open); RegisterHotkey("Main Window", "Start Emulation"); RegisterHotkey("Main Window", "Fullscreen", QKeySequence::FullScreen); - RegisterHotkey("Main Window", "Exit Fullscreen", QKeySequence::Cancel, Qt::ApplicationShortcut); + RegisterHotkey("Main Window", "Exit Fullscreen", QKeySequence(Qt::Key_Escape), + Qt::ApplicationShortcut); LoadHotkeys(); connect(GetHotkey("Main Window", "Load File", this), &QShortcut::activated, this,