diff --git a/stratosphere/libstratosphere/source/multithreadedwaitablemanager.cpp b/stratosphere/libstratosphere/source/multithreadedwaitablemanager.cpp index 02c2714e7..6acc53a65 100644 --- a/stratosphere/libstratosphere/source/multithreadedwaitablemanager.cpp +++ b/stratosphere/libstratosphere/source/multithreadedwaitablemanager.cpp @@ -53,7 +53,7 @@ IWaitable *MultiThreadedWaitableManager::get_waitable() { for (auto & waitable : this->waitables) { waitable->update_priority(); } - } else if (rc != 0xF601) { + } else if (rc != 0xF601 && rc != 0xE401) { /* TODO: Panic. When can this happen? */ } else { for (int i = 0; i < handle_index; i++) { diff --git a/stratosphere/pm/source/pm_debug_monitor.cpp b/stratosphere/pm/source/pm_debug_monitor.cpp index 755ff1f12..6ac95f5da 100644 --- a/stratosphere/pm/source/pm_debug_monitor.cpp +++ b/stratosphere/pm/source/pm_debug_monitor.cpp @@ -95,8 +95,8 @@ std::tuple DebugMonitorService::launch_debug_process(u64 pid) { std::tuple DebugMonitorService::get_title_process_id(u64 tid) { Registration::AutoProcessListLock auto_lock; - Registration::Process *proc = Registration::GetProcessByTitleId(tid); - if (proc != NULL) { + std::shared_ptr proc = Registration::GetProcessByTitleId(tid); + if (proc != nullptr) { return {0, proc->pid}; } else { return {0x20F, 0}; @@ -112,7 +112,7 @@ std::tuple DebugMonitorService::enable_debug_for_tid(u64 t std::tuple DebugMonitorService::get_application_process_id() { Registration::AutoProcessListLock auto_lock; - Registration::Process *app_proc; + std::shared_ptr app_proc; if (Registration::HasApplicationProcess(&app_proc)) { return {0, app_proc->pid}; } @@ -126,7 +126,7 @@ std::tuple DebugMonitorService::enable_debug_for_applicati } std::tuple DebugMonitorService::get_process_handle(u64 pid) { - Registration::Process *proc = Registration::GetProcess(pid); + std::shared_ptr proc = Registration::GetProcess(pid); if(proc == NULL) { return {0x20F, 0}; } diff --git a/stratosphere/pm/source/pm_info.cpp b/stratosphere/pm/source/pm_info.cpp index 629efbc49..c4844f968 100644 --- a/stratosphere/pm/source/pm_info.cpp +++ b/stratosphere/pm/source/pm_info.cpp @@ -24,7 +24,7 @@ Result InformationService::handle_deferred() { std::tuple InformationService::get_title_id(u64 pid) { Registration::AutoProcessListLock auto_lock; - Registration::Process *proc = Registration::GetProcess(pid); + std::shared_ptr proc = Registration::GetProcess(pid); if (proc != NULL) { return {0x0, proc->tid_sid.title_id}; } else { diff --git a/stratosphere/pm/source/pm_process_track.cpp b/stratosphere/pm/source/pm_process_track.cpp index 0cb379051..507979126 100644 --- a/stratosphere/pm/source/pm_process_track.cpp +++ b/stratosphere/pm/source/pm_process_track.cpp @@ -5,9 +5,9 @@ void ProcessTracking::MainLoop(void *arg) { /* Make a new waitable manager. */ - WaitableManager *process_waiter = new WaitableManager(U64_MAX); + MultiThreadedWaitableManager *process_waiter = new MultiThreadedWaitableManager(1, U64_MAX); process_waiter->add_waitable(Registration::GetProcessLaunchStartEvent()); - process_waiter->add_waitable(Registration::GetProcessList()); + Registration::SetProcessListManager(process_waiter); /* Service processes. */ process_waiter->process(); diff --git a/stratosphere/pm/source/pm_process_wait.hpp b/stratosphere/pm/source/pm_process_wait.hpp index 15bd80af5..6cffcded1 100644 --- a/stratosphere/pm/source/pm_process_wait.hpp +++ b/stratosphere/pm/source/pm_process_wait.hpp @@ -4,23 +4,19 @@ class ProcessWaiter final : public IWaitable { public: - Registration::Process process; + std::shared_ptr process; - ProcessWaiter(Registration::Process p) : process(p) { - + ProcessWaiter(std::shared_ptr p) : process(p) { + /* ... */ } - ProcessWaiter(Registration::Process *p) { - this->process = *p; - } - - Registration::Process *get_process() { - return &this->process; + std::shared_ptr get_process() { + return this->process; } /* IWaitable */ Handle get_handle() override { - return this->process.handle; + return this->process->handle; } void handle_deferred() override { @@ -28,16 +24,16 @@ class ProcessWaiter final : public IWaitable { } Result handle_signaled(u64 timeout) override { - Registration::HandleSignaledProcess(this->get_process()); - return 0; + return Registration::HandleSignaledProcess(this->get_process()); } }; -class ProcessList final : public IWaitable { +class ProcessList final { private: HosRecursiveMutex mutex; + WaitableManager *manager; public: - std::vector process_waiters; + std::vector> processes; void Lock() { this->mutex.Lock(); @@ -51,20 +47,12 @@ class ProcessList final : public IWaitable { return this->mutex.TryLock(); } - /* IWaitable */ - - Handle get_handle() override { - /* TODO: Panic, because we don't have a handle. */ - return 0; + void set_manager(WaitableManager *manager) { + this->manager = manager; } - void handle_deferred() override { - /* TODO: Panic, because we can never be deferred. */ - } - - Result handle_signaled(u64 timeout) override { - /* TODO: Panic, because we can never be signaled. */ - return 0; + WaitableManager *get_manager() { + return this->manager; } }; diff --git a/stratosphere/pm/source/pm_registration.cpp b/stratosphere/pm/source/pm_registration.cpp index 85e20db95..405903515 100644 --- a/stratosphere/pm/source/pm_registration.cpp +++ b/stratosphere/pm/source/pm_registration.cpp @@ -40,6 +40,11 @@ void Registration::AutoProcessListLock::Unlock() { this->has_lock = false; } + +void Registration::SetProcessListManager(WaitableManager *m) { + g_process_list.set_manager(m); +} + void Registration::InitializeSystemResources() { g_process_event = new SystemEvent(NULL, &IEvent::PanicCallback); g_debug_title_event = new SystemEvent(NULL, &IEvent::PanicCallback); @@ -59,10 +64,6 @@ IWaitable *Registration::GetProcessLaunchStartEvent() { return g_process_launch_start_event; } -IWaitable *Registration::GetProcessList() { - return &g_process_list; -} - void Registration::HandleProcessLaunch() { LoaderProgramInfo program_info = {0}; Result rc; @@ -132,7 +133,7 @@ void Registration::HandleProcessLaunch() { } /* Add process to the list. */ - Registration::AddProcessToList(&new_process); + Registration::AddProcessToList(std::make_shared(new_process)); /* Signal, if relevant. */ if (new_process.tid_sid.title_id == g_debug_on_launch_tid.load()) { @@ -166,6 +167,7 @@ SM_REGISTRATION_FAILED: FS_REGISTRATION_FAILED: if (R_FAILED(rc)) { svcCloseHandle(new_process.handle); + new_process.handle = 0; } PROCESS_CREATION_FAILED: @@ -188,7 +190,7 @@ Result Registration::LaunchDebugProcess(u64 pid) { LoaderProgramInfo program_info = {0}; Result rc; - Process *proc = GetProcess(pid); + std::shared_ptr proc = GetProcess(pid); if (proc == NULL) { return 0x20F; } @@ -232,7 +234,7 @@ Result Registration::LaunchProcessByTidSid(TidSid tid_sid, u64 launch_flags, u64 return LaunchProcess(tid_sid.title_id, tid_sid.storage_id, launch_flags, out_pid); }; -void Registration::HandleSignaledProcess(Process *process) { +Result Registration::HandleSignaledProcess(std::shared_ptr process) { u64 tmp; /* Reset the signal. */ @@ -279,8 +281,7 @@ void Registration::HandleSignaledProcess(Process *process) { } else { FinalizeExitedProcess(process); } - //Reboot(); - break; + return 0xF601; case ProcessState_DebugSuspended: if (process->flags & 8) { process->flags |= 0x30; @@ -288,9 +289,10 @@ void Registration::HandleSignaledProcess(Process *process) { } break; } + return 0; } -void Registration::FinalizeExitedProcess(Process *process) { +void Registration::FinalizeExitedProcess(std::shared_ptr process) { AutoProcessListLock auto_lock; bool signal_debug_process_5x = kernelAbove500() && process->flags & 1; /* Unregister with FS. */ @@ -308,11 +310,12 @@ void Registration::FinalizeExitedProcess(Process *process) { /* Close the process's handle. */ svcCloseHandle(process->handle); + process->handle = 0; /* Insert into dead process list, if relevant. */ if (signal_debug_process_5x) { g_dead_process_list.Lock(); - g_dead_process_list.process_waiters.push_back(new ProcessWaiter(process)); + g_dead_process_list.processes.push_back(process); g_dead_process_list.Unlock(); } @@ -325,22 +328,22 @@ void Registration::FinalizeExitedProcess(Process *process) { } } -void Registration::AddProcessToList(Process *process) { +void Registration::AddProcessToList(std::shared_ptr process) { AutoProcessListLock auto_lock; - g_process_list.process_waiters.push_back(new ProcessWaiter(process)); + g_process_list.processes.push_back(process); + g_process_list.get_manager()->add_waitable(new ProcessWaiter(process)); } void Registration::RemoveProcessFromList(u64 pid) { AutoProcessListLock auto_lock; /* Remove process from list. */ - for (unsigned int i = 0; i < g_process_list.process_waiters.size(); i++) { - ProcessWaiter *pw = g_process_list.process_waiters[i]; - Registration::Process *process = pw->get_process(); - if (process->pid == pid) { - g_process_list.process_waiters.erase(g_process_list.process_waiters.begin() + i); + for (unsigned int i = 0; i < g_process_list.processes.size(); i++) { + std::shared_ptr process = g_process_list.processes[i]; + if (process->pid == pid) { + g_process_list.processes.erase(g_process_list.processes.begin() + i); svcCloseHandle(process->handle); - delete pw; + process->handle = 0; break; } } @@ -350,8 +353,7 @@ void Registration::SetProcessState(u64 pid, ProcessState new_state) { AutoProcessListLock auto_lock; /* Set process state. */ - for (auto &pw : g_process_list.process_waiters) { - Registration::Process *process = pw->get_process(); + for (auto &process : g_process_list.processes) { if (process->pid == pid) { process->state = new_state; break; @@ -359,13 +361,12 @@ void Registration::SetProcessState(u64 pid, ProcessState new_state) { } } -bool Registration::HasApplicationProcess(Process **out) { +bool Registration::HasApplicationProcess(std::shared_ptr *out) { AutoProcessListLock auto_lock; - for (auto &pw : g_process_list.process_waiters) { - Registration::Process *process = pw->get_process(); + for (auto &process : g_process_list.processes) { if (process->flags & 0x40) { - if (out != NULL) { + if (out != nullptr) { *out = process; } return true; @@ -375,30 +376,28 @@ bool Registration::HasApplicationProcess(Process **out) { return false; } -Registration::Process *Registration::GetProcess(u64 pid) { +std::shared_ptr Registration::GetProcess(u64 pid) { AutoProcessListLock auto_lock; - for (auto &pw : g_process_list.process_waiters) { - Process *p = pw->get_process(); - if (p->pid == pid) { - return p; + for (auto &process : g_process_list.processes) { + if (process->pid == pid) { + return process; } } - return NULL; + return nullptr; } -Registration::Process *Registration::GetProcessByTitleId(u64 tid) { +std::shared_ptr Registration::GetProcessByTitleId(u64 tid) { AutoProcessListLock auto_lock; - for (auto &pw : g_process_list.process_waiters) { - Process *p = pw->get_process(); - if (p->tid_sid.title_id == tid) { - return p; + for (auto &process : g_process_list.processes) { + if (process->tid_sid.title_id == tid) { + return process; } } - return NULL; + return nullptr; } @@ -407,10 +406,9 @@ Result Registration::GetDebugProcessIds(u64 *out_pids, u32 max_out, u32 *num_out u32 num = 0; - for (auto &pw : g_process_list.process_waiters) { - Process *p = pw->get_process(); - if (p->flags & 4 && num < max_out) { - out_pids[num++] = p->pid; + for (auto &process : g_process_list.processes) { + if (process->flags & 4 && num < max_out) { + out_pids[num++] = process->pid; } } @@ -425,8 +423,7 @@ Handle Registration::GetProcessEventHandle() { void Registration::GetProcessEventType(u64 *out_pid, u64 *out_type) { AutoProcessListLock auto_lock; - for (auto &pw : g_process_list.process_waiters) { - Process *p = pw->get_process(); + for (auto &p : g_process_list.processes) { if (kernelAbove200() && p->state >= ProcessState_DebugDetached && p->flags & 0x100) { p->flags &= ~0x100; *out_pid = p->pid; @@ -454,13 +451,11 @@ void Registration::GetProcessEventType(u64 *out_pid, u64 *out_type) { if (kernelAbove500()) { auto_lock.Unlock(); g_dead_process_list.Lock(); - if (g_dead_process_list.process_waiters.size()) { - ProcessWaiter *pw = g_dead_process_list.process_waiters[0]; - Registration::Process *process = pw->get_process(); - g_dead_process_list.process_waiters.erase(g_dead_process_list.process_waiters.begin()); + if (g_dead_process_list.processes.size()) { + std::shared_ptr process = g_dead_process_list.processes[0]; + g_dead_process_list.processes.erase(g_dead_process_list.processes.begin()); *out_pid = process->pid; *out_type = 1; - delete pw; g_dead_process_list.Unlock(); return; } diff --git a/stratosphere/pm/source/pm_registration.hpp b/stratosphere/pm/source/pm_registration.hpp index 6232b946b..5e13b4143 100644 --- a/stratosphere/pm/source/pm_registration.hpp +++ b/stratosphere/pm/source/pm_registration.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include #define LAUNCHFLAGS_NOTIFYWHENEXITED(flags) (flags & 1) #define LAUNCHFLAGS_STARTSUSPENDED(flags) (flags & (kernelAbove500() ? 0x10 : 0x2)) @@ -42,18 +43,18 @@ class Registration { static void InitializeSystemResources(); static IWaitable *GetProcessLaunchStartEvent(); + static void SetProcessListManager(WaitableManager *m); static Result ProcessLaunchStartCallback(void *arg, Handle *handles, size_t num_handles, u64 timeout); - static IWaitable *GetProcessList(); - static void HandleSignaledProcess(Process *process); - static void FinalizeExitedProcess(Process *process); + static Result HandleSignaledProcess(std::shared_ptr process); + static void FinalizeExitedProcess(std::shared_ptr process); - static void AddProcessToList(Process *process); + static void AddProcessToList(std::shared_ptr process); static void RemoveProcessFromList(u64 pid); static void SetProcessState(u64 pid, ProcessState new_state); - static Process *GetProcess(u64 pid); - static Process *GetProcessByTitleId(u64 tid); + static std::shared_ptr GetProcess(u64 pid); + static std::shared_ptr GetProcessByTitleId(u64 tid); static Result GetDebugProcessIds(u64 *out_pids, u32 max_out, u32 *num_out); static Handle GetProcessEventHandle(); static void GetProcessEventType(u64 *out_pid, u64 *out_type); @@ -68,6 +69,6 @@ class Registration { static Result LaunchProcess(u64 title_id, FsStorageId storage_id, u64 launch_flags, u64 *out_pid); static Result LaunchProcessByTidSid(TidSid tid_sid, u64 launch_flags, u64 *out_pid); - static bool HasApplicationProcess(Process **out); + static bool HasApplicationProcess(std::shared_ptr *out); }; diff --git a/stratosphere/pm/source/pm_shell.cpp b/stratosphere/pm/source/pm_shell.cpp index 1e352fb79..282adb593 100644 --- a/stratosphere/pm/source/pm_shell.cpp +++ b/stratosphere/pm/source/pm_shell.cpp @@ -92,7 +92,7 @@ std::tuple ShellService::launch_process(u64 launch_flags, Registrat std::tuple ShellService::terminate_process_id(u64 pid) { Registration::AutoProcessListLock auto_lock; - Registration::Process *proc = Registration::GetProcess(pid); + std::shared_ptr proc = Registration::GetProcess(pid); if (proc != NULL) { return {svcTerminateProcess(proc->handle)}; } else { @@ -103,7 +103,7 @@ std::tuple ShellService::terminate_process_id(u64 pid) { std::tuple ShellService::terminate_title_id(u64 tid) { Registration::AutoProcessListLock auto_lock; - Registration::Process *proc = Registration::GetProcessByTitleId(tid); + std::shared_ptr proc = Registration::GetProcessByTitleId(tid); if (proc != NULL) { return {svcTerminateProcess(proc->handle)}; } else { @@ -124,7 +124,7 @@ std::tuple ShellService::get_process_event_type() { std::tuple ShellService::finalize_exited_process(u64 pid) { Registration::AutoProcessListLock auto_lock; - Registration::Process *proc = Registration::GetProcess(pid); + std::shared_ptr proc = Registration::GetProcess(pid); if (proc == NULL) { return {0x20F}; } else if (proc->state != ProcessState_Exited) { @@ -138,7 +138,7 @@ std::tuple ShellService::finalize_exited_process(u64 pid) { std::tuple ShellService::clear_process_notification_flag(u64 pid) { Registration::AutoProcessListLock auto_lock; - Registration::Process *proc = Registration::GetProcess(pid); + std::shared_ptr proc = Registration::GetProcess(pid); if (proc != NULL) { proc->flags &= ~2; return {0x0}; @@ -159,7 +159,7 @@ std::tuple ShellService::notify_boot_finished() { std::tuple ShellService::get_application_process_id() { Registration::AutoProcessListLock auto_lock; - Registration::Process *app_proc; + std::shared_ptr app_proc; if (Registration::HasApplicationProcess(&app_proc)) { return {0, app_proc->pid}; }