hle: kernel: svc: Cleanup KEvent/KReadableEvent/KWritableEvent SVCs.
This commit is contained in:
		@@ -49,7 +49,6 @@ ResultCode KReadableEvent::Reset() {
 | 
				
			|||||||
    R_UNLESS_NOLOG(is_signaled, Svc::ResultInvalidState);
 | 
					    R_UNLESS_NOLOG(is_signaled, Svc::ResultInvalidState);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    is_signaled = false;
 | 
					    is_signaled = false;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    return RESULT_SUCCESS;
 | 
					    return RESULT_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,6 +23,7 @@
 | 
				
			|||||||
#include "core/hle/kernel/memory/page_table.h"
 | 
					#include "core/hle/kernel/memory/page_table.h"
 | 
				
			||||||
#include "core/hle/kernel/memory/slab_heap.h"
 | 
					#include "core/hle/kernel/memory/slab_heap.h"
 | 
				
			||||||
#include "core/hle/kernel/process.h"
 | 
					#include "core/hle/kernel/process.h"
 | 
				
			||||||
 | 
					#include "core/hle/kernel/svc_results.h"
 | 
				
			||||||
#include "core/hle/lock.h"
 | 
					#include "core/hle/lock.h"
 | 
				
			||||||
#include "core/memory.h"
 | 
					#include "core/memory.h"
 | 
				
			||||||
#include "core/settings.h"
 | 
					#include "core/settings.h"
 | 
				
			||||||
@@ -241,18 +242,16 @@ void Process::UnregisterThread(const KThread* thread) {
 | 
				
			|||||||
    thread_list.remove(thread);
 | 
					    thread_list.remove(thread);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ResultCode Process::ClearSignalState() {
 | 
					ResultCode Process::Reset() {
 | 
				
			||||||
    KScopedSchedulerLock lock(system.Kernel());
 | 
					    // Lock the process and the scheduler.
 | 
				
			||||||
    if (status == ProcessStatus::Exited) {
 | 
					    KScopedLightLock lk(state_lock);
 | 
				
			||||||
        LOG_ERROR(Kernel, "called on a terminated process instance.");
 | 
					    KScopedSchedulerLock sl{kernel};
 | 
				
			||||||
        return ERR_INVALID_STATE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!is_signaled) {
 | 
					    // Validate that we're in a state that we can reset.
 | 
				
			||||||
        LOG_ERROR(Kernel, "called on a process instance that isn't signaled.");
 | 
					    R_UNLESS(status != ProcessStatus::Exited, Svc::ResultInvalidState);
 | 
				
			||||||
        return ERR_INVALID_STATE;
 | 
					    R_UNLESS(is_signaled, Svc::ResultInvalidState);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Clear signaled.
 | 
				
			||||||
    is_signaled = false;
 | 
					    is_signaled = false;
 | 
				
			||||||
    return RESULT_SUCCESS;
 | 
					    return RESULT_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -312,7 +312,7 @@ public:
 | 
				
			|||||||
    /// @pre The process must be in a signaled state. If this is called on a
 | 
					    /// @pre The process must be in a signaled state. If this is called on a
 | 
				
			||||||
    ///      process instance that is not signaled, ERR_INVALID_STATE will be
 | 
					    ///      process instance that is not signaled, ERR_INVALID_STATE will be
 | 
				
			||||||
    ///      returned.
 | 
					    ///      returned.
 | 
				
			||||||
    ResultCode ClearSignalState();
 | 
					    ResultCode Reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Loads process-specifics configuration info with metadata provided
 | 
					     * Loads process-specifics configuration info with metadata provided
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,7 @@
 | 
				
			|||||||
#include "common/fiber.h"
 | 
					#include "common/fiber.h"
 | 
				
			||||||
#include "common/logging/log.h"
 | 
					#include "common/logging/log.h"
 | 
				
			||||||
#include "common/microprofile.h"
 | 
					#include "common/microprofile.h"
 | 
				
			||||||
 | 
					#include "common/scope_exit.h"
 | 
				
			||||||
#include "common/string_util.h"
 | 
					#include "common/string_util.h"
 | 
				
			||||||
#include "core/arm/exclusive_monitor.h"
 | 
					#include "core/arm/exclusive_monitor.h"
 | 
				
			||||||
#include "core/core.h"
 | 
					#include "core/core.h"
 | 
				
			||||||
@@ -1726,20 +1727,28 @@ static ResultCode CloseHandle32(Core::System& system, Handle handle) {
 | 
				
			|||||||
static ResultCode ResetSignal(Core::System& system, Handle handle) {
 | 
					static ResultCode ResetSignal(Core::System& system, Handle handle) {
 | 
				
			||||||
    LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle);
 | 
					    LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get the current handle table.
 | 
				
			||||||
    const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
 | 
					    const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto event = handle_table.Get<KReadableEvent>(handle);
 | 
					    // Try to reset as readable event.
 | 
				
			||||||
    if (event) {
 | 
					    {
 | 
				
			||||||
        return event->Reset();
 | 
					        auto readable_event = handle_table.Get<KReadableEvent>(handle);
 | 
				
			||||||
 | 
					        if (readable_event) {
 | 
				
			||||||
 | 
					            return readable_event->Reset();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto process = handle_table.Get<Process>(handle);
 | 
					    // Try to reset as process.
 | 
				
			||||||
    if (process) {
 | 
					    {
 | 
				
			||||||
        return process->ClearSignalState();
 | 
					        auto process = handle_table.Get<Process>(handle);
 | 
				
			||||||
 | 
					        if (process) {
 | 
				
			||||||
 | 
					            return process->Reset();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LOG_ERROR(Kernel_SVC, "Invalid handle (0x{:08X})", handle);
 | 
					    LOG_ERROR(Kernel_SVC, "invalid handle (0x{:08X})", handle);
 | 
				
			||||||
    return ERR_INVALID_HANDLE;
 | 
					
 | 
				
			||||||
 | 
					    return Svc::ResultInvalidHandle;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ResultCode ResetSignal32(Core::System& system, Handle handle) {
 | 
					static ResultCode ResetSignal32(Core::System& system, Handle handle) {
 | 
				
			||||||
@@ -1867,80 +1876,92 @@ static ResultCode SetThreadCoreMask32(Core::System& system, Handle thread_handle
 | 
				
			|||||||
    return SetThreadCoreMask(system, thread_handle, core_id, affinity_mask);
 | 
					    return SetThreadCoreMask(system, thread_handle, core_id, affinity_mask);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ResultCode CreateEvent(Core::System& system, Handle* write_handle, Handle* read_handle) {
 | 
					static ResultCode SignalEvent(Core::System& system, Handle event_handle) {
 | 
				
			||||||
 | 
					    LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get the current handle table.
 | 
				
			||||||
 | 
					    const HandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get the writable event.
 | 
				
			||||||
 | 
					    auto writable_event = handle_table.Get<KWritableEvent>(event_handle);
 | 
				
			||||||
 | 
					    R_UNLESS(writable_event, Svc::ResultInvalidHandle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return writable_event->Signal();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static ResultCode SignalEvent32(Core::System& system, Handle event_handle) {
 | 
				
			||||||
 | 
					    return SignalEvent(system, event_handle);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static ResultCode ClearEvent(Core::System& system, Handle event_handle) {
 | 
				
			||||||
 | 
					    LOG_TRACE(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get the current handle table.
 | 
				
			||||||
 | 
					    const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Try to clear the writable event.
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        auto writable_event = handle_table.Get<KWritableEvent>(event_handle);
 | 
				
			||||||
 | 
					        if (writable_event) {
 | 
				
			||||||
 | 
					            return writable_event->Clear();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Try to clear the readable event.
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        auto readable_event = handle_table.Get<KReadableEvent>(event_handle);
 | 
				
			||||||
 | 
					        if (readable_event) {
 | 
				
			||||||
 | 
					            return readable_event->Clear();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LOG_ERROR(Kernel_SVC, "Event handle does not exist, event_handle=0x{:08X}", event_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return Svc::ResultInvalidHandle;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static ResultCode ClearEvent32(Core::System& system, Handle event_handle) {
 | 
				
			||||||
 | 
					    return ClearEvent(system, event_handle);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) {
 | 
				
			||||||
    LOG_DEBUG(Kernel_SVC, "called");
 | 
					    LOG_DEBUG(Kernel_SVC, "called");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get the kernel reference and handle table.
 | 
				
			||||||
    auto& kernel = system.Kernel();
 | 
					    auto& kernel = system.Kernel();
 | 
				
			||||||
    const auto event = KEvent::Create(kernel, "CreateEvent");
 | 
					 | 
				
			||||||
    event->Initialize();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable();
 | 
					    HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Create a new event.
 | 
				
			||||||
 | 
					    const auto event = KEvent::Create(kernel, "CreateEvent");
 | 
				
			||||||
 | 
					    R_UNLESS(event != nullptr, Svc::ResultOutOfResource);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Initialize the event.
 | 
				
			||||||
 | 
					    event->Initialize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Add the writable event to the handle table.
 | 
				
			||||||
    const auto write_create_result = handle_table.Create(event->GetWritableEvent());
 | 
					    const auto write_create_result = handle_table.Create(event->GetWritableEvent());
 | 
				
			||||||
    if (write_create_result.Failed()) {
 | 
					    if (write_create_result.Failed()) {
 | 
				
			||||||
        return write_create_result.Code();
 | 
					        return write_create_result.Code();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    *write_handle = *write_create_result;
 | 
					    *out_write = *write_create_result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Add the writable event to the handle table.
 | 
				
			||||||
 | 
					    auto handle_guard = SCOPE_GUARD({ handle_table.Close(*write_create_result); });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Add the readable event to the handle table.
 | 
				
			||||||
    const auto read_create_result = handle_table.Create(event->GetReadableEvent());
 | 
					    const auto read_create_result = handle_table.Create(event->GetReadableEvent());
 | 
				
			||||||
    if (read_create_result.Failed()) {
 | 
					    if (read_create_result.Failed()) {
 | 
				
			||||||
        handle_table.Close(*write_create_result);
 | 
					 | 
				
			||||||
        return read_create_result.Code();
 | 
					        return read_create_result.Code();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    *read_handle = *read_create_result;
 | 
					    *out_read = *read_create_result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LOG_DEBUG(Kernel_SVC,
 | 
					    // We succeeded.
 | 
				
			||||||
              "successful. Writable event handle=0x{:08X}, Readable event handle=0x{:08X}",
 | 
					    handle_guard.Cancel();
 | 
				
			||||||
              *write_create_result, *read_create_result);
 | 
					 | 
				
			||||||
    return RESULT_SUCCESS;
 | 
					    return RESULT_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ResultCode CreateEvent32(Core::System& system, Handle* write_handle, Handle* read_handle) {
 | 
					static ResultCode CreateEvent32(Core::System& system, Handle* out_write, Handle* out_read) {
 | 
				
			||||||
    return CreateEvent(system, write_handle, read_handle);
 | 
					    return CreateEvent(system, out_write, out_read);
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static ResultCode ClearEvent(Core::System& system, Handle handle) {
 | 
					 | 
				
			||||||
    LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    auto writable_event = handle_table.Get<KWritableEvent>(handle);
 | 
					 | 
				
			||||||
    if (writable_event) {
 | 
					 | 
				
			||||||
        writable_event->Clear();
 | 
					 | 
				
			||||||
        return RESULT_SUCCESS;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    auto readable_event = handle_table.Get<KReadableEvent>(handle);
 | 
					 | 
				
			||||||
    if (readable_event) {
 | 
					 | 
				
			||||||
        readable_event->Clear();
 | 
					 | 
				
			||||||
        return RESULT_SUCCESS;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    LOG_ERROR(Kernel_SVC, "Event handle does not exist, handle=0x{:08X}", handle);
 | 
					 | 
				
			||||||
    return ERR_INVALID_HANDLE;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static ResultCode ClearEvent32(Core::System& system, Handle handle) {
 | 
					 | 
				
			||||||
    return ClearEvent(system, handle);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static ResultCode SignalEvent(Core::System& system, Handle handle) {
 | 
					 | 
				
			||||||
    LOG_DEBUG(Kernel_SVC, "called. Handle=0x{:08X}", handle);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    HandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
 | 
					 | 
				
			||||||
    auto writable_event = handle_table.Get<KWritableEvent>(handle);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!writable_event) {
 | 
					 | 
				
			||||||
        LOG_ERROR(Kernel_SVC, "Non-existent writable event handle used (0x{:08X})", handle);
 | 
					 | 
				
			||||||
        return ERR_INVALID_HANDLE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    writable_event->Signal();
 | 
					 | 
				
			||||||
    return RESULT_SUCCESS;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static ResultCode SignalEvent32(Core::System& system, Handle handle) {
 | 
					 | 
				
			||||||
    return SignalEvent(system, handle);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) {
 | 
					static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,7 @@ namespace Kernel::Svc {
 | 
				
			|||||||
constexpr ResultCode ResultNoSynchronizationObject{ErrorModule::Kernel, 57};
 | 
					constexpr ResultCode ResultNoSynchronizationObject{ErrorModule::Kernel, 57};
 | 
				
			||||||
constexpr ResultCode ResultTerminationRequested{ErrorModule::Kernel, 59};
 | 
					constexpr ResultCode ResultTerminationRequested{ErrorModule::Kernel, 59};
 | 
				
			||||||
constexpr ResultCode ResultInvalidAddress{ErrorModule::Kernel, 102};
 | 
					constexpr ResultCode ResultInvalidAddress{ErrorModule::Kernel, 102};
 | 
				
			||||||
 | 
					constexpr ResultCode ResultOutOfResource{ErrorModule::Kernel, 103};
 | 
				
			||||||
constexpr ResultCode ResultInvalidCurrentMemory{ErrorModule::Kernel, 106};
 | 
					constexpr ResultCode ResultInvalidCurrentMemory{ErrorModule::Kernel, 106};
 | 
				
			||||||
constexpr ResultCode ResultInvalidPriority{ErrorModule::Kernel, 112};
 | 
					constexpr ResultCode ResultInvalidPriority{ErrorModule::Kernel, 112};
 | 
				
			||||||
constexpr ResultCode ResultInvalidCoreId{ErrorModule::Kernel, 113};
 | 
					constexpr ResultCode ResultInvalidCoreId{ErrorModule::Kernel, 113};
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user