mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-11-04 12:34:39 +08:00 
			
		
		
		
	hle_ipc: Add SleepClientThread to block current thread within HLE routines.
This commit is contained in:
		
							parent
							
								
									2faa83ca13
								
							
						
					
					
						commit
						c86af6939c
					
				@ -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;
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@
 | 
			
		||||
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <boost/container/small_vector.hpp>
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
@ -25,6 +26,7 @@ class Domain;
 | 
			
		||||
class HandleTable;
 | 
			
		||||
class HLERequestContext;
 | 
			
		||||
class Process;
 | 
			
		||||
class Event;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Interface implemented by HLE Session handlers.
 | 
			
		||||
@ -103,6 +105,24 @@ public:
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
    /// Populates this context with data from the requesting process/thread.
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user