hle: kernel: svc: Cleanup KEvent/KReadableEvent/KWritableEvent SVCs.

merge-requests/60/head
bunnei 2021-01-31 16:55:11 +07:00
parent 18175c71ed
commit eba3c59a61
5 changed files with 96 additions and 76 deletions

@ -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};