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(); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // Try to reset as process. | ||||||
|  |     { | ||||||
|         auto process = handle_table.Get<Process>(handle); |         auto process = handle_table.Get<Process>(handle); | ||||||
|         if (process) { |         if (process) { | ||||||
|         return process->ClearSignalState(); |             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