diff options
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 70 |
1 files changed, 32 insertions, 38 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 8050359be..c6334f91c 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -1745,16 +1745,16 @@ static ResultCode ResetSignal(Core::System& system, Handle handle) { | |||
| 1745 | 1745 | ||
| 1746 | // Try to reset as readable event. | 1746 | // Try to reset as readable event. |
| 1747 | { | 1747 | { |
| 1748 | auto readable_event = handle_table.Get<KReadableEvent>(handle); | 1748 | KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(handle); |
| 1749 | if (readable_event) { | 1749 | if (readable_event.IsNotNull()) { |
| 1750 | return readable_event->Reset(); | 1750 | return readable_event->Reset(); |
| 1751 | } | 1751 | } |
| 1752 | } | 1752 | } |
| 1753 | 1753 | ||
| 1754 | // Try to reset as process. | 1754 | // Try to reset as process. |
| 1755 | { | 1755 | { |
| 1756 | auto process = handle_table.Get<Process>(handle); | 1756 | KScopedAutoObject process = handle_table.GetObject<Process>(handle); |
| 1757 | if (process) { | 1757 | if (process.IsNotNull()) { |
| 1758 | return process->Reset(); | 1758 | return process->Reset(); |
| 1759 | } | 1759 | } |
| 1760 | } | 1760 | } |
| @@ -1885,27 +1885,12 @@ static ResultCode SetThreadCoreMask32(Core::System& system, Handle thread_handle | |||
| 1885 | static ResultCode SignalEvent(Core::System& system, Handle event_handle) { | 1885 | static ResultCode SignalEvent(Core::System& system, Handle event_handle) { |
| 1886 | LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); | 1886 | LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); |
| 1887 | 1887 | ||
| 1888 | auto& kernel = system.Kernel(); | ||
| 1889 | // Get the current handle table. | 1888 | // Get the current handle table. |
| 1890 | const HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); | 1889 | const HandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); |
| 1891 | |||
| 1892 | // Reserve a new event from the process resource limit. | ||
| 1893 | KScopedResourceReservation event_reservation(kernel.CurrentProcess(), | ||
| 1894 | LimitableResource::Events); | ||
| 1895 | if (!event_reservation.Succeeded()) { | ||
| 1896 | LOG_ERROR(Kernel, "Could not reserve a new event"); | ||
| 1897 | return ResultResourceLimitedExceeded; | ||
| 1898 | } | ||
| 1899 | 1890 | ||
| 1900 | // Get the writable event. | 1891 | // Get the writable event. |
| 1901 | auto writable_event = handle_table.Get<KWritableEvent>(event_handle); | 1892 | KScopedAutoObject writable_event = handle_table.GetObject<KWritableEvent>(event_handle); |
| 1902 | if (!writable_event) { | 1893 | R_UNLESS(writable_event.IsNotNull(), ResultInvalidHandle); |
| 1903 | LOG_ERROR(Kernel_SVC, "Invalid event handle provided (handle={:08X})", event_handle); | ||
| 1904 | return ResultInvalidHandle; | ||
| 1905 | } | ||
| 1906 | |||
| 1907 | // Commit the successfuly reservation. | ||
| 1908 | event_reservation.Commit(); | ||
| 1909 | 1894 | ||
| 1910 | return writable_event->Signal(); | 1895 | return writable_event->Signal(); |
| 1911 | } | 1896 | } |
| @@ -1922,16 +1907,16 @@ static ResultCode ClearEvent(Core::System& system, Handle event_handle) { | |||
| 1922 | 1907 | ||
| 1923 | // Try to clear the writable event. | 1908 | // Try to clear the writable event. |
| 1924 | { | 1909 | { |
| 1925 | auto writable_event = handle_table.Get<KWritableEvent>(event_handle); | 1910 | KScopedAutoObject writable_event = handle_table.GetObject<KWritableEvent>(event_handle); |
| 1926 | if (writable_event) { | 1911 | if (writable_event.IsNotNull()) { |
| 1927 | return writable_event->Clear(); | 1912 | return writable_event->Clear(); |
| 1928 | } | 1913 | } |
| 1929 | } | 1914 | } |
| 1930 | 1915 | ||
| 1931 | // Try to clear the readable event. | 1916 | // Try to clear the readable event. |
| 1932 | { | 1917 | { |
| 1933 | auto readable_event = handle_table.Get<KReadableEvent>(event_handle); | 1918 | KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(event_handle); |
| 1934 | if (readable_event) { | 1919 | if (readable_event.IsNotNull()) { |
| 1935 | return readable_event->Clear(); | 1920 | return readable_event->Clear(); |
| 1936 | } | 1921 | } |
| 1937 | } | 1922 | } |
| @@ -1950,7 +1935,12 @@ static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* o | |||
| 1950 | 1935 | ||
| 1951 | // Get the kernel reference and handle table. | 1936 | // Get the kernel reference and handle table. |
| 1952 | auto& kernel = system.Kernel(); | 1937 | auto& kernel = system.Kernel(); |
| 1953 | HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); | 1938 | auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); |
| 1939 | |||
| 1940 | // Reserve a new event from the process resource limit | ||
| 1941 | KScopedResourceReservation event_reservation(kernel.CurrentProcess(), | ||
| 1942 | LimitableResource::Events); | ||
| 1943 | R_UNLESS(event_reservation.Succeeded(), ResultResourceLimitedExceeded); | ||
| 1954 | 1944 | ||
| 1955 | // Create a new event. | 1945 | // Create a new event. |
| 1956 | KEvent* event = KEvent::Create(kernel); | 1946 | KEvent* event = KEvent::Create(kernel); |
| @@ -1959,22 +1949,26 @@ static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* o | |||
| 1959 | // Initialize the event. | 1949 | // Initialize the event. |
| 1960 | event->Initialize("CreateEvent"); | 1950 | event->Initialize("CreateEvent"); |
| 1961 | 1951 | ||
| 1952 | // Commit the thread reservation. | ||
| 1953 | event_reservation.Commit(); | ||
| 1954 | |||
| 1955 | // Ensure that we clean up the event (and its only references are handle table) on function end. | ||
| 1956 | SCOPE_EXIT({ | ||
| 1957 | event->GetWritableEvent().Close(); | ||
| 1958 | event->GetReadableEvent().Close(); | ||
| 1959 | }); | ||
| 1960 | |||
| 1961 | // Register the event. | ||
| 1962 | KEvent::Register(kernel, event); | ||
| 1963 | |||
| 1962 | // Add the writable event to the handle table. | 1964 | // Add the writable event to the handle table. |
| 1963 | const auto write_create_result = handle_table.Create(event->GetWritableEvent().get()); | 1965 | R_TRY(handle_table.Add(out_write, std::addressof(event->GetWritableEvent()))); |
| 1964 | if (write_create_result.Failed()) { | ||
| 1965 | return write_create_result.Code(); | ||
| 1966 | } | ||
| 1967 | *out_write = *write_create_result; | ||
| 1968 | 1966 | ||
| 1969 | // Add the writable event to the handle table. | 1967 | // Add the writable event to the handle table. |
| 1970 | auto handle_guard = SCOPE_GUARD({ handle_table.Remove(*write_create_result); }); | 1968 | auto handle_guard = SCOPE_GUARD({ handle_table.Remove(*out_write); }); |
| 1971 | 1969 | ||
| 1972 | // Add the readable event to the handle table. | 1970 | // Add the readable event to the handle table. |
| 1973 | const auto read_create_result = handle_table.Create(event->GetReadableEvent()); | 1971 | R_TRY(handle_table.Add(out_read, std::addressof(event->GetReadableEvent()))); |
| 1974 | if (read_create_result.Failed()) { | ||
| 1975 | return read_create_result.Code(); | ||
| 1976 | } | ||
| 1977 | *out_read = *read_create_result; | ||
| 1978 | 1972 | ||
| 1979 | // We succeeded. | 1973 | // We succeeded. |
| 1980 | handle_guard.Cancel(); | 1974 | handle_guard.Cancel(); |