summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/k_readable_event.cpp1
-rw-r--r--src/core/hle/kernel/process.cpp19
-rw-r--r--src/core/hle/kernel/process.h2
-rw-r--r--src/core/hle/kernel/svc.cpp135
-rw-r--r--src/core/hle/kernel/svc_results.h1
5 files changed, 89 insertions, 69 deletions
diff --git a/src/core/hle/kernel/k_readable_event.cpp b/src/core/hle/kernel/k_readable_event.cpp
index 0fa895c56..cd15aa529 100644
--- a/src/core/hle/kernel/k_readable_event.cpp
+++ b/src/core/hle/kernel/k_readable_event.cpp
@@ -49,7 +49,6 @@ ResultCode KReadableEvent::Reset() {
49 R_UNLESS_NOLOG(is_signaled, Svc::ResultInvalidState); 49 R_UNLESS_NOLOG(is_signaled, Svc::ResultInvalidState);
50 50
51 is_signaled = false; 51 is_signaled = false;
52
53 return RESULT_SUCCESS; 52 return RESULT_SUCCESS;
54} 53}
55 54
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index afdb27c54..2286b292d 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -23,6 +23,7 @@
23#include "core/hle/kernel/memory/page_table.h" 23#include "core/hle/kernel/memory/page_table.h"
24#include "core/hle/kernel/memory/slab_heap.h" 24#include "core/hle/kernel/memory/slab_heap.h"
25#include "core/hle/kernel/process.h" 25#include "core/hle/kernel/process.h"
26#include "core/hle/kernel/svc_results.h"
26#include "core/hle/lock.h" 27#include "core/hle/lock.h"
27#include "core/memory.h" 28#include "core/memory.h"
28#include "core/settings.h" 29#include "core/settings.h"
@@ -241,18 +242,16 @@ void Process::UnregisterThread(const KThread* thread) {
241 thread_list.remove(thread); 242 thread_list.remove(thread);
242} 243}
243 244
244ResultCode Process::ClearSignalState() { 245ResultCode Process::Reset() {
245 KScopedSchedulerLock lock(system.Kernel()); 246 // Lock the process and the scheduler.
246 if (status == ProcessStatus::Exited) { 247 KScopedLightLock lk(state_lock);
247 LOG_ERROR(Kernel, "called on a terminated process instance."); 248 KScopedSchedulerLock sl{kernel};
248 return ERR_INVALID_STATE;
249 }
250 249
251 if (!is_signaled) { 250 // Validate that we're in a state that we can reset.
252 LOG_ERROR(Kernel, "called on a process instance that isn't signaled."); 251 R_UNLESS(status != ProcessStatus::Exited, Svc::ResultInvalidState);
253 return ERR_INVALID_STATE; 252 R_UNLESS(is_signaled, Svc::ResultInvalidState);
254 }
255 253
254 // Clear signaled.
256 is_signaled = false; 255 is_signaled = false;
257 return RESULT_SUCCESS; 256 return RESULT_SUCCESS;
258} 257}
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index c8af76ce8..320b0f347 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -312,7 +312,7 @@ public:
312 /// @pre The process must be in a signaled state. If this is called on a 312 /// @pre The process must be in a signaled state. If this is called on a
313 /// process instance that is not signaled, ERR_INVALID_STATE will be 313 /// process instance that is not signaled, ERR_INVALID_STATE will be
314 /// returned. 314 /// returned.
315 ResultCode ClearSignalState(); 315 ResultCode Reset();
316 316
317 /** 317 /**
318 * Loads process-specifics configuration info with metadata provided 318 * Loads process-specifics configuration info with metadata provided
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 9d036f45d..edf208eff 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -14,6 +14,7 @@
14#include "common/fiber.h" 14#include "common/fiber.h"
15#include "common/logging/log.h" 15#include "common/logging/log.h"
16#include "common/microprofile.h" 16#include "common/microprofile.h"
17#include "common/scope_exit.h"
17#include "common/string_util.h" 18#include "common/string_util.h"
18#include "core/arm/exclusive_monitor.h" 19#include "core/arm/exclusive_monitor.h"
19#include "core/core.h" 20#include "core/core.h"
@@ -1726,20 +1727,28 @@ static ResultCode CloseHandle32(Core::System& system, Handle handle) {
1726static ResultCode ResetSignal(Core::System& system, Handle handle) { 1727static ResultCode ResetSignal(Core::System& system, Handle handle) {
1727 LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle); 1728 LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle);
1728 1729
1730 // Get the current handle table.
1729 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); 1731 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1730 1732
1731 auto event = handle_table.Get<KReadableEvent>(handle); 1733 // Try to reset as readable event.
1732 if (event) { 1734 {
1733 return event->Reset(); 1735 auto readable_event = handle_table.Get<KReadableEvent>(handle);
1736 if (readable_event) {
1737 return readable_event->Reset();
1738 }
1734 } 1739 }
1735 1740
1736 auto process = handle_table.Get<Process>(handle); 1741 // Try to reset as process.
1737 if (process) { 1742 {
1738 return process->ClearSignalState(); 1743 auto process = handle_table.Get<Process>(handle);
1744 if (process) {
1745 return process->Reset();
1746 }
1739 } 1747 }
1740 1748
1741 LOG_ERROR(Kernel_SVC, "Invalid handle (0x{:08X})", handle); 1749 LOG_ERROR(Kernel_SVC, "invalid handle (0x{:08X})", handle);
1742 return ERR_INVALID_HANDLE; 1750
1751 return Svc::ResultInvalidHandle;
1743} 1752}
1744 1753
1745static ResultCode ResetSignal32(Core::System& system, Handle handle) { 1754static ResultCode ResetSignal32(Core::System& system, Handle handle) {
@@ -1867,80 +1876,92 @@ static ResultCode SetThreadCoreMask32(Core::System& system, Handle thread_handle
1867 return SetThreadCoreMask(system, thread_handle, core_id, affinity_mask); 1876 return SetThreadCoreMask(system, thread_handle, core_id, affinity_mask);
1868} 1877}
1869 1878
1870static ResultCode CreateEvent(Core::System& system, Handle* write_handle, Handle* read_handle) { 1879static ResultCode SignalEvent(Core::System& system, Handle event_handle) {
1871 LOG_DEBUG(Kernel_SVC, "called"); 1880 LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle);
1872 1881
1873 auto& kernel = system.Kernel(); 1882 // Get the current handle table.
1874 const auto event = KEvent::Create(kernel, "CreateEvent"); 1883 const HandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1875 event->Initialize();
1876 1884
1877 HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); 1885 // Get the writable event.
1886 auto writable_event = handle_table.Get<KWritableEvent>(event_handle);
1887 R_UNLESS(writable_event, Svc::ResultInvalidHandle);
1878 1888
1879 const auto write_create_result = handle_table.Create(event->GetWritableEvent()); 1889 return writable_event->Signal();
1880 if (write_create_result.Failed()) {
1881 return write_create_result.Code();
1882 }
1883 *write_handle = *write_create_result;
1884
1885 const auto read_create_result = handle_table.Create(event->GetReadableEvent());
1886 if (read_create_result.Failed()) {
1887 handle_table.Close(*write_create_result);
1888 return read_create_result.Code();
1889 }
1890 *read_handle = *read_create_result;
1891
1892 LOG_DEBUG(Kernel_SVC,
1893 "successful. Writable event handle=0x{:08X}, Readable event handle=0x{:08X}",
1894 *write_create_result, *read_create_result);
1895 return RESULT_SUCCESS;
1896} 1890}
1897 1891
1898static ResultCode CreateEvent32(Core::System& system, Handle* write_handle, Handle* read_handle) { 1892static ResultCode SignalEvent32(Core::System& system, Handle event_handle) {
1899 return CreateEvent(system, write_handle, read_handle); 1893 return SignalEvent(system, event_handle);
1900} 1894}
1901 1895
1902static ResultCode ClearEvent(Core::System& system, Handle handle) { 1896static ResultCode ClearEvent(Core::System& system, Handle event_handle) {
1903 LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle); 1897 LOG_TRACE(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle);
1904 1898
1899 // Get the current handle table.
1905 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); 1900 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1906 1901
1907 auto writable_event = handle_table.Get<KWritableEvent>(handle); 1902 // Try to clear the writable event.
1908 if (writable_event) { 1903 {
1909 writable_event->Clear(); 1904 auto writable_event = handle_table.Get<KWritableEvent>(event_handle);
1910 return RESULT_SUCCESS; 1905 if (writable_event) {
1906 return writable_event->Clear();
1907 }
1911 } 1908 }
1912 1909
1913 auto readable_event = handle_table.Get<KReadableEvent>(handle); 1910 // Try to clear the readable event.
1914 if (readable_event) { 1911 {
1915 readable_event->Clear(); 1912 auto readable_event = handle_table.Get<KReadableEvent>(event_handle);
1916 return RESULT_SUCCESS; 1913 if (readable_event) {
1914 return readable_event->Clear();
1915 }
1917 } 1916 }
1918 1917
1919 LOG_ERROR(Kernel_SVC, "Event handle does not exist, handle=0x{:08X}", handle); 1918 LOG_ERROR(Kernel_SVC, "Event handle does not exist, event_handle=0x{:08X}", event_handle);
1920 return ERR_INVALID_HANDLE; 1919
1920 return Svc::ResultInvalidHandle;
1921} 1921}
1922 1922
1923static ResultCode ClearEvent32(Core::System& system, Handle handle) { 1923static ResultCode ClearEvent32(Core::System& system, Handle event_handle) {
1924 return ClearEvent(system, handle); 1924 return ClearEvent(system, event_handle);
1925} 1925}
1926 1926
1927static ResultCode SignalEvent(Core::System& system, Handle handle) { 1927static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) {
1928 LOG_DEBUG(Kernel_SVC, "called. Handle=0x{:08X}", handle); 1928 LOG_DEBUG(Kernel_SVC, "called");
1929 1929
1930 HandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); 1930 // Get the kernel reference and handle table.
1931 auto writable_event = handle_table.Get<KWritableEvent>(handle); 1931 auto& kernel = system.Kernel();
1932 HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable();
1932 1933
1933 if (!writable_event) { 1934 // Create a new event.
1934 LOG_ERROR(Kernel_SVC, "Non-existent writable event handle used (0x{:08X})", handle); 1935 const auto event = KEvent::Create(kernel, "CreateEvent");
1935 return ERR_INVALID_HANDLE; 1936 R_UNLESS(event != nullptr, Svc::ResultOutOfResource);
1937
1938 // Initialize the event.
1939 event->Initialize();
1940
1941 // Add the writable event to the handle table.
1942 const auto write_create_result = handle_table.Create(event->GetWritableEvent());
1943 if (write_create_result.Failed()) {
1944 return write_create_result.Code();
1945 }
1946 *out_write = *write_create_result;
1947
1948 // Add the writable event to the handle table.
1949 auto handle_guard = SCOPE_GUARD({ handle_table.Close(*write_create_result); });
1950
1951 // Add the readable event to the handle table.
1952 const auto read_create_result = handle_table.Create(event->GetReadableEvent());
1953 if (read_create_result.Failed()) {
1954 return read_create_result.Code();
1936 } 1955 }
1956 *out_read = *read_create_result;
1937 1957
1938 writable_event->Signal(); 1958 // We succeeded.
1959 handle_guard.Cancel();
1939 return RESULT_SUCCESS; 1960 return RESULT_SUCCESS;
1940} 1961}
1941 1962
1942static ResultCode SignalEvent32(Core::System& system, Handle handle) { 1963static ResultCode CreateEvent32(Core::System& system, Handle* out_write, Handle* out_read) {
1943 return SignalEvent(system, handle); 1964 return CreateEvent(system, out_write, out_read);
1944} 1965}
1945 1966
1946static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) { 1967static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) {
diff --git a/src/core/hle/kernel/svc_results.h b/src/core/hle/kernel/svc_results.h
index 7b897fbce..204cd989d 100644
--- a/src/core/hle/kernel/svc_results.h
+++ b/src/core/hle/kernel/svc_results.h
@@ -11,6 +11,7 @@ namespace Kernel::Svc {
11constexpr ResultCode ResultNoSynchronizationObject{ErrorModule::Kernel, 57}; 11constexpr ResultCode ResultNoSynchronizationObject{ErrorModule::Kernel, 57};
12constexpr ResultCode ResultTerminationRequested{ErrorModule::Kernel, 59}; 12constexpr ResultCode ResultTerminationRequested{ErrorModule::Kernel, 59};
13constexpr ResultCode ResultInvalidAddress{ErrorModule::Kernel, 102}; 13constexpr ResultCode ResultInvalidAddress{ErrorModule::Kernel, 102};
14constexpr ResultCode ResultOutOfResource{ErrorModule::Kernel, 103};
14constexpr ResultCode ResultInvalidCurrentMemory{ErrorModule::Kernel, 106}; 15constexpr ResultCode ResultInvalidCurrentMemory{ErrorModule::Kernel, 106};
15constexpr ResultCode ResultInvalidPriority{ErrorModule::Kernel, 112}; 16constexpr ResultCode ResultInvalidPriority{ErrorModule::Kernel, 112};
16constexpr ResultCode ResultInvalidCoreId{ErrorModule::Kernel, 113}; 17constexpr ResultCode ResultInvalidCoreId{ErrorModule::Kernel, 113};