hle_ipc: Use event pair for SleepClientThread

master
Zach Hilman 2018-11-26 18:32:52 +07:00
parent c61d2a2841
commit a56fc84e7a
2 changed files with 22 additions and 19 deletions

@ -15,13 +15,14 @@
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/core.h" #include "core/core.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"
#include "core/hle/kernel/object.h" #include "core/hle/kernel/object.h"
#include "core/hle/kernel/process.h" #include "core/hle/kernel/process.h"
#include "core/hle/kernel/readable_event.h"
#include "core/hle/kernel/server_session.h" #include "core/hle/kernel/server_session.h"
#include "core/hle/kernel/writable_event.h"
#include "core/memory.h" #include "core/memory.h"
namespace Kernel { namespace Kernel {
@ -36,11 +37,9 @@ void SessionRequestHandler::ClientDisconnected(const SharedPtr<ServerSession>& s
boost::range::remove_erase(connected_sessions, server_session); boost::range::remove_erase(connected_sessions, server_session);
} }
SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread, SharedPtr<WritableEvent> HLERequestContext::SleepClientThread(
const std::string& reason, u64 timeout, SharedPtr<Thread> thread, const std::string& reason, u64 timeout, WakeupCallback&& callback,
WakeupCallback&& callback, SharedPtr<WritableEvent> writable_event, SharedPtr<ReadableEvent> readable_event) {
Kernel::SharedPtr<Kernel::Event> event) {
// Put the client thread to sleep until the wait event is signaled or the timeout expires. // Put the client thread to sleep until the wait event is signaled or the timeout expires.
thread->SetWakeupCallback([context = *this, callback]( thread->SetWakeupCallback([context = *this, callback](
ThreadWakeupReason reason, SharedPtr<Thread> thread, ThreadWakeupReason reason, SharedPtr<Thread> thread,
@ -51,23 +50,23 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread,
return true; return true;
}); });
if (!event) { auto& kernel = Core::System::GetInstance().Kernel();
if (!writable_event || !readable_event) {
// Create event if not provided // Create event if not provided
auto& kernel = Core::System::GetInstance().Kernel(); std::tie(writable_event, readable_event) = WritableEvent::CreateEventPair(
event = kernel, Kernel::ResetType::OneShot, "HLE Pause Event: " + reason);
Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "HLE Pause Event: " + reason);
} }
event->Clear(); writable_event->Clear();
thread->SetStatus(ThreadStatus::WaitHLEEvent); thread->SetStatus(ThreadStatus::WaitHLEEvent);
thread->SetWaitObjects({event}); thread->SetWaitObjects({readable_event});
event->AddWaitingThread(thread); readable_event->AddWaitingThread(thread);
if (timeout > 0) { if (timeout > 0) {
thread->WakeAfterDelay(timeout); thread->WakeAfterDelay(timeout);
} }
return event; return writable_event;
} }
HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session) HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session)

@ -24,10 +24,11 @@ class ServiceFrameworkBase;
namespace Kernel { namespace Kernel {
class Domain; class Domain;
class Event;
class HandleTable; class HandleTable;
class HLERequestContext; class HLERequestContext;
class Process; class Process;
class ReadableEvent;
class WritableEvent;
/** /**
* Interface implemented by HLE Session handlers. * Interface implemented by HLE Session handlers.
@ -119,12 +120,15 @@ public:
* @param callback Callback to be invoked when the thread is resumed. This callback must write * @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 * the entire command response once again, regardless of the state of it before this function
* was called. * was called.
* @param event Event to use to wake up the thread. If unspecified, an event will be created. * @param writable_event Event to use to wake up the thread. If unspecified, an event will be
* created.
* @param readable_event Event to be bound to the thread to wake up upon.
* @returns Event that when signaled will resume the thread and call the callback function. * @returns Event that when signaled will resume the thread and call the callback function.
*/ */
SharedPtr<Event> SleepClientThread(SharedPtr<Thread> thread, const std::string& reason, SharedPtr<WritableEvent> SleepClientThread(SharedPtr<Thread> thread, const std::string& reason,
u64 timeout, WakeupCallback&& callback, u64 timeout, WakeupCallback&& callback,
Kernel::SharedPtr<Kernel::Event> event = nullptr); SharedPtr<WritableEvent> writable_event = nullptr,
SharedPtr<ReadableEvent> readable_event = nullptr);
/// Populates this context with data from the requesting process/thread. /// Populates this context with data from the requesting process/thread.
ResultCode PopulateFromIncomingCommandBuffer(const HandleTable& handle_table, ResultCode PopulateFromIncomingCommandBuffer(const HandleTable& handle_table,