|
@@ -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);
|
|
|
|
|
- if (event) {
|
|
|
|
|
- return event->Reset();
|
|
|
|
|
|
|
+ // Try to reset as readable event.
|
|
|
|
|
+ {
|
|
|
|
|
+ auto readable_event = handle_table.Get<KReadableEvent>(handle);
|
|
|
|
|
+ if (readable_event) {
|
|
|
|
|
+ return readable_event->Reset();
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- auto process = handle_table.Get<Process>(handle);
|
|
|
|
|
- if (process) {
|
|
|
|
|
- return process->ClearSignalState();
|
|
|
|
|
|
|
+ // Try to reset as process.
|
|
|
|
|
+ {
|
|
|
|
|
+ auto process = handle_table.Get<Process>(handle);
|
|
|
|
|
+ if (process) {
|
|
|
|
|
+ return process->Reset();
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- LOG_ERROR(Kernel_SVC, "Invalid handle (0x{:08X})", handle);
|
|
|
|
|
- return ERR_INVALID_HANDLE;
|
|
|
|
|
|
|
+ LOG_ERROR(Kernel_SVC, "invalid handle (0x{:08X})", 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) {
|
|
|
|
|
- LOG_DEBUG(Kernel_SVC, "called");
|
|
|
|
|
|
|
+static ResultCode SignalEvent(Core::System& system, Handle event_handle) {
|
|
|
|
|
+ LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle);
|
|
|
|
|
|
|
|
- auto& kernel = system.Kernel();
|
|
|
|
|
- const auto event = KEvent::Create(kernel, "CreateEvent");
|
|
|
|
|
- event->Initialize();
|
|
|
|
|
|
|
+ // Get the current handle table.
|
|
|
|
|
+ const HandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
|
|
|
|
|
|
|
- HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable();
|
|
|
|
|
|
|
+ // Get the writable event.
|
|
|
|
|
+ auto writable_event = handle_table.Get<KWritableEvent>(event_handle);
|
|
|
|
|
+ R_UNLESS(writable_event, Svc::ResultInvalidHandle);
|
|
|
|
|
|
|
|
- const auto write_create_result = handle_table.Create(event->GetWritableEvent());
|
|
|
|
|
- if (write_create_result.Failed()) {
|
|
|
|
|
- return write_create_result.Code();
|
|
|
|
|
- }
|
|
|
|
|
- *write_handle = *write_create_result;
|
|
|
|
|
-
|
|
|
|
|
- const auto read_create_result = handle_table.Create(event->GetReadableEvent());
|
|
|
|
|
- if (read_create_result.Failed()) {
|
|
|
|
|
- handle_table.Close(*write_create_result);
|
|
|
|
|
- return read_create_result.Code();
|
|
|
|
|
- }
|
|
|
|
|
- *read_handle = *read_create_result;
|
|
|
|
|
-
|
|
|
|
|
- LOG_DEBUG(Kernel_SVC,
|
|
|
|
|
- "successful. Writable event handle=0x{:08X}, Readable event handle=0x{:08X}",
|
|
|
|
|
- *write_create_result, *read_create_result);
|
|
|
|
|
- return RESULT_SUCCESS;
|
|
|
|
|
|
|
+ return writable_event->Signal();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static ResultCode CreateEvent32(Core::System& system, Handle* write_handle, Handle* read_handle) {
|
|
|
|
|
- return CreateEvent(system, write_handle, read_handle);
|
|
|
|
|
|
|
+static ResultCode SignalEvent32(Core::System& system, Handle event_handle) {
|
|
|
|
|
+ return SignalEvent(system, event_handle);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static ResultCode ClearEvent(Core::System& system, Handle handle) {
|
|
|
|
|
- LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", 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();
|
|
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;
|
|
|
|
|
|
|
+ // Try to clear the writable event.
|
|
|
|
|
+ {
|
|
|
|
|
+ auto writable_event = handle_table.Get<KWritableEvent>(event_handle);
|
|
|
|
|
+ if (writable_event) {
|
|
|
|
|
+ return writable_event->Clear();
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- auto readable_event = handle_table.Get<KReadableEvent>(handle);
|
|
|
|
|
- if (readable_event) {
|
|
|
|
|
- readable_event->Clear();
|
|
|
|
|
- return RESULT_SUCCESS;
|
|
|
|
|
|
|
+ // 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, handle=0x{:08X}", handle);
|
|
|
|
|
- return ERR_INVALID_HANDLE;
|
|
|
|
|
|
|
+ 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 handle) {
|
|
|
|
|
- return ClearEvent(system, handle);
|
|
|
|
|
|
|
+static ResultCode ClearEvent32(Core::System& system, Handle event_handle) {
|
|
|
|
|
+ return ClearEvent(system, event_handle);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static ResultCode SignalEvent(Core::System& system, Handle handle) {
|
|
|
|
|
- LOG_DEBUG(Kernel_SVC, "called. Handle=0x{:08X}", handle);
|
|
|
|
|
|
|
+static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) {
|
|
|
|
|
+ LOG_DEBUG(Kernel_SVC, "called");
|
|
|
|
|
|
|
|
- HandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
|
|
|
|
- auto writable_event = handle_table.Get<KWritableEvent>(handle);
|
|
|
|
|
|
|
+ // Get the kernel reference and handle table.
|
|
|
|
|
+ auto& kernel = system.Kernel();
|
|
|
|
|
+ HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable();
|
|
|
|
|
|
|
|
- if (!writable_event) {
|
|
|
|
|
- LOG_ERROR(Kernel_SVC, "Non-existent writable event handle used (0x{:08X})", handle);
|
|
|
|
|
- return ERR_INVALID_HANDLE;
|
|
|
|
|
|
|
+ // 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());
|
|
|
|
|
+ if (write_create_result.Failed()) {
|
|
|
|
|
+ return write_create_result.Code();
|
|
|
|
|
+ }
|
|
|
|
|
+ *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());
|
|
|
|
|
+ if (read_create_result.Failed()) {
|
|
|
|
|
+ return read_create_result.Code();
|
|
|
}
|
|
}
|
|
|
|
|
+ *out_read = *read_create_result;
|
|
|
|
|
|
|
|
- writable_event->Signal();
|
|
|
|
|
|
|
+ // We succeeded.
|
|
|
|
|
+ handle_guard.Cancel();
|
|
|
return RESULT_SUCCESS;
|
|
return RESULT_SUCCESS;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static ResultCode SignalEvent32(Core::System& system, Handle handle) {
|
|
|
|
|
- return SignalEvent(system, handle);
|
|
|
|
|
|
|
+static ResultCode CreateEvent32(Core::System& system, Handle* out_write, Handle* out_read) {
|
|
|
|
|
+ return CreateEvent(system, out_write, out_read);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
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) {
|