PM: Fix remaining issues, now works properly again.

This commit is contained in:
Michael Scire 2018-06-15 00:47:07 -06:00
parent 4d36697080
commit f41b780c0a
8 changed files with 78 additions and 94 deletions

View file

@ -53,7 +53,7 @@ IWaitable *MultiThreadedWaitableManager::get_waitable() {
for (auto & waitable : this->waitables) { for (auto & waitable : this->waitables) {
waitable->update_priority(); waitable->update_priority();
} }
} else if (rc != 0xF601) { } else if (rc != 0xF601 && rc != 0xE401) {
/* TODO: Panic. When can this happen? */ /* TODO: Panic. When can this happen? */
} else { } else {
for (int i = 0; i < handle_index; i++) { for (int i = 0; i < handle_index; i++) {

View file

@ -95,8 +95,8 @@ std::tuple<Result> DebugMonitorService::launch_debug_process(u64 pid) {
std::tuple<Result, u64> DebugMonitorService::get_title_process_id(u64 tid) { std::tuple<Result, u64> DebugMonitorService::get_title_process_id(u64 tid) {
Registration::AutoProcessListLock auto_lock; Registration::AutoProcessListLock auto_lock;
Registration::Process *proc = Registration::GetProcessByTitleId(tid); std::shared_ptr<Registration::Process> proc = Registration::GetProcessByTitleId(tid);
if (proc != NULL) { if (proc != nullptr) {
return {0, proc->pid}; return {0, proc->pid};
} else { } else {
return {0x20F, 0}; return {0x20F, 0};
@ -112,7 +112,7 @@ std::tuple<Result, CopiedHandle> DebugMonitorService::enable_debug_for_tid(u64 t
std::tuple<Result, u64> DebugMonitorService::get_application_process_id() { std::tuple<Result, u64> DebugMonitorService::get_application_process_id() {
Registration::AutoProcessListLock auto_lock; Registration::AutoProcessListLock auto_lock;
Registration::Process *app_proc; std::shared_ptr<Registration::Process> app_proc;
if (Registration::HasApplicationProcess(&app_proc)) { if (Registration::HasApplicationProcess(&app_proc)) {
return {0, app_proc->pid}; return {0, app_proc->pid};
} }
@ -126,7 +126,7 @@ std::tuple<Result, CopiedHandle> DebugMonitorService::enable_debug_for_applicati
} }
std::tuple<Result, CopiedHandle> DebugMonitorService::get_process_handle(u64 pid) { std::tuple<Result, CopiedHandle> DebugMonitorService::get_process_handle(u64 pid) {
Registration::Process *proc = Registration::GetProcess(pid); std::shared_ptr<Registration::Process> proc = Registration::GetProcess(pid);
if(proc == NULL) { if(proc == NULL) {
return {0x20F, 0}; return {0x20F, 0};
} }

View file

@ -24,7 +24,7 @@ Result InformationService::handle_deferred() {
std::tuple<Result, u64> InformationService::get_title_id(u64 pid) { std::tuple<Result, u64> InformationService::get_title_id(u64 pid) {
Registration::AutoProcessListLock auto_lock; Registration::AutoProcessListLock auto_lock;
Registration::Process *proc = Registration::GetProcess(pid); std::shared_ptr<Registration::Process> proc = Registration::GetProcess(pid);
if (proc != NULL) { if (proc != NULL) {
return {0x0, proc->tid_sid.title_id}; return {0x0, proc->tid_sid.title_id};
} else { } else {

View file

@ -5,9 +5,9 @@
void ProcessTracking::MainLoop(void *arg) { void ProcessTracking::MainLoop(void *arg) {
/* Make a new waitable manager. */ /* 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::GetProcessLaunchStartEvent());
process_waiter->add_waitable(Registration::GetProcessList()); Registration::SetProcessListManager(process_waiter);
/* Service processes. */ /* Service processes. */
process_waiter->process(); process_waiter->process();

View file

@ -4,23 +4,19 @@
class ProcessWaiter final : public IWaitable { class ProcessWaiter final : public IWaitable {
public: public:
Registration::Process process; std::shared_ptr<Registration::Process> process;
ProcessWaiter(Registration::Process p) : process(p) {
ProcessWaiter(std::shared_ptr<Registration::Process> p) : process(p) {
/* ... */
} }
ProcessWaiter(Registration::Process *p) { std::shared_ptr<Registration::Process> get_process() {
this->process = *p; return this->process;
}
Registration::Process *get_process() {
return &this->process;
} }
/* IWaitable */ /* IWaitable */
Handle get_handle() override { Handle get_handle() override {
return this->process.handle; return this->process->handle;
} }
void handle_deferred() override { void handle_deferred() override {
@ -28,16 +24,16 @@ class ProcessWaiter final : public IWaitable {
} }
Result handle_signaled(u64 timeout) override { Result handle_signaled(u64 timeout) override {
Registration::HandleSignaledProcess(this->get_process()); return Registration::HandleSignaledProcess(this->get_process());
return 0;
} }
}; };
class ProcessList final : public IWaitable { class ProcessList final {
private: private:
HosRecursiveMutex mutex; HosRecursiveMutex mutex;
WaitableManager *manager;
public: public:
std::vector<ProcessWaiter *> process_waiters; std::vector<std::shared_ptr<Registration::Process>> processes;
void Lock() { void Lock() {
this->mutex.Lock(); this->mutex.Lock();
@ -51,20 +47,12 @@ class ProcessList final : public IWaitable {
return this->mutex.TryLock(); return this->mutex.TryLock();
} }
/* IWaitable */ void set_manager(WaitableManager *manager) {
this->manager = manager;
Handle get_handle() override {
/* TODO: Panic, because we don't have a handle. */
return 0;
} }
void handle_deferred() override { WaitableManager *get_manager() {
/* TODO: Panic, because we can never be deferred. */ return this->manager;
}
Result handle_signaled(u64 timeout) override {
/* TODO: Panic, because we can never be signaled. */
return 0;
} }
}; };

View file

@ -40,6 +40,11 @@ void Registration::AutoProcessListLock::Unlock() {
this->has_lock = false; this->has_lock = false;
} }
void Registration::SetProcessListManager(WaitableManager *m) {
g_process_list.set_manager(m);
}
void Registration::InitializeSystemResources() { void Registration::InitializeSystemResources() {
g_process_event = new SystemEvent(NULL, &IEvent::PanicCallback); g_process_event = new SystemEvent(NULL, &IEvent::PanicCallback);
g_debug_title_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; return g_process_launch_start_event;
} }
IWaitable *Registration::GetProcessList() {
return &g_process_list;
}
void Registration::HandleProcessLaunch() { void Registration::HandleProcessLaunch() {
LoaderProgramInfo program_info = {0}; LoaderProgramInfo program_info = {0};
Result rc; Result rc;
@ -132,7 +133,7 @@ void Registration::HandleProcessLaunch() {
} }
/* Add process to the list. */ /* Add process to the list. */
Registration::AddProcessToList(&new_process); Registration::AddProcessToList(std::make_shared<Registration::Process>(new_process));
/* Signal, if relevant. */ /* Signal, if relevant. */
if (new_process.tid_sid.title_id == g_debug_on_launch_tid.load()) { if (new_process.tid_sid.title_id == g_debug_on_launch_tid.load()) {
@ -166,6 +167,7 @@ SM_REGISTRATION_FAILED:
FS_REGISTRATION_FAILED: FS_REGISTRATION_FAILED:
if (R_FAILED(rc)) { if (R_FAILED(rc)) {
svcCloseHandle(new_process.handle); svcCloseHandle(new_process.handle);
new_process.handle = 0;
} }
PROCESS_CREATION_FAILED: PROCESS_CREATION_FAILED:
@ -188,7 +190,7 @@ Result Registration::LaunchDebugProcess(u64 pid) {
LoaderProgramInfo program_info = {0}; LoaderProgramInfo program_info = {0};
Result rc; Result rc;
Process *proc = GetProcess(pid); std::shared_ptr<Registration::Process> proc = GetProcess(pid);
if (proc == NULL) { if (proc == NULL) {
return 0x20F; 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); 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<Registration::Process> process) {
u64 tmp; u64 tmp;
/* Reset the signal. */ /* Reset the signal. */
@ -279,8 +281,7 @@ void Registration::HandleSignaledProcess(Process *process) {
} else { } else {
FinalizeExitedProcess(process); FinalizeExitedProcess(process);
} }
//Reboot(); return 0xF601;
break;
case ProcessState_DebugSuspended: case ProcessState_DebugSuspended:
if (process->flags & 8) { if (process->flags & 8) {
process->flags |= 0x30; process->flags |= 0x30;
@ -288,9 +289,10 @@ void Registration::HandleSignaledProcess(Process *process) {
} }
break; break;
} }
return 0;
} }
void Registration::FinalizeExitedProcess(Process *process) { void Registration::FinalizeExitedProcess(std::shared_ptr<Registration::Process> process) {
AutoProcessListLock auto_lock; AutoProcessListLock auto_lock;
bool signal_debug_process_5x = kernelAbove500() && process->flags & 1; bool signal_debug_process_5x = kernelAbove500() && process->flags & 1;
/* Unregister with FS. */ /* Unregister with FS. */
@ -308,11 +310,12 @@ void Registration::FinalizeExitedProcess(Process *process) {
/* Close the process's handle. */ /* Close the process's handle. */
svcCloseHandle(process->handle); svcCloseHandle(process->handle);
process->handle = 0;
/* Insert into dead process list, if relevant. */ /* Insert into dead process list, if relevant. */
if (signal_debug_process_5x) { if (signal_debug_process_5x) {
g_dead_process_list.Lock(); 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(); 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<Registration::Process> process) {
AutoProcessListLock auto_lock; 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) { void Registration::RemoveProcessFromList(u64 pid) {
AutoProcessListLock auto_lock; AutoProcessListLock auto_lock;
/* Remove process from list. */ /* Remove process from list. */
for (unsigned int i = 0; i < g_process_list.process_waiters.size(); i++) { for (unsigned int i = 0; i < g_process_list.processes.size(); i++) {
ProcessWaiter *pw = g_process_list.process_waiters[i]; std::shared_ptr<Registration::Process> process = g_process_list.processes[i];
Registration::Process *process = pw->get_process();
if (process->pid == pid) { if (process->pid == pid) {
g_process_list.process_waiters.erase(g_process_list.process_waiters.begin() + i); g_process_list.processes.erase(g_process_list.processes.begin() + i);
svcCloseHandle(process->handle); svcCloseHandle(process->handle);
delete pw; process->handle = 0;
break; break;
} }
} }
@ -350,8 +353,7 @@ void Registration::SetProcessState(u64 pid, ProcessState new_state) {
AutoProcessListLock auto_lock; AutoProcessListLock auto_lock;
/* Set process state. */ /* Set process state. */
for (auto &pw : g_process_list.process_waiters) { for (auto &process : g_process_list.processes) {
Registration::Process *process = pw->get_process();
if (process->pid == pid) { if (process->pid == pid) {
process->state = new_state; process->state = new_state;
break; break;
@ -359,13 +361,12 @@ void Registration::SetProcessState(u64 pid, ProcessState new_state) {
} }
} }
bool Registration::HasApplicationProcess(Process **out) { bool Registration::HasApplicationProcess(std::shared_ptr<Registration::Process> *out) {
AutoProcessListLock auto_lock; AutoProcessListLock auto_lock;
for (auto &pw : g_process_list.process_waiters) { for (auto &process : g_process_list.processes) {
Registration::Process *process = pw->get_process();
if (process->flags & 0x40) { if (process->flags & 0x40) {
if (out != NULL) { if (out != nullptr) {
*out = process; *out = process;
} }
return true; return true;
@ -375,30 +376,28 @@ bool Registration::HasApplicationProcess(Process **out) {
return false; return false;
} }
Registration::Process *Registration::GetProcess(u64 pid) { std::shared_ptr<Registration::Process> Registration::GetProcess(u64 pid) {
AutoProcessListLock auto_lock; AutoProcessListLock auto_lock;
for (auto &pw : g_process_list.process_waiters) { for (auto &process : g_process_list.processes) {
Process *p = pw->get_process(); if (process->pid == pid) {
if (p->pid == pid) { return process;
return p;
} }
} }
return NULL; return nullptr;
} }
Registration::Process *Registration::GetProcessByTitleId(u64 tid) { std::shared_ptr<Registration::Process> Registration::GetProcessByTitleId(u64 tid) {
AutoProcessListLock auto_lock; AutoProcessListLock auto_lock;
for (auto &pw : g_process_list.process_waiters) { for (auto &process : g_process_list.processes) {
Process *p = pw->get_process(); if (process->tid_sid.title_id == tid) {
if (p->tid_sid.title_id == tid) { return process;
return p;
} }
} }
return NULL; return nullptr;
} }
@ -407,10 +406,9 @@ Result Registration::GetDebugProcessIds(u64 *out_pids, u32 max_out, u32 *num_out
u32 num = 0; u32 num = 0;
for (auto &pw : g_process_list.process_waiters) { for (auto &process : g_process_list.processes) {
Process *p = pw->get_process(); if (process->flags & 4 && num < max_out) {
if (p->flags & 4 && num < max_out) { out_pids[num++] = process->pid;
out_pids[num++] = p->pid;
} }
} }
@ -425,8 +423,7 @@ Handle Registration::GetProcessEventHandle() {
void Registration::GetProcessEventType(u64 *out_pid, u64 *out_type) { void Registration::GetProcessEventType(u64 *out_pid, u64 *out_type) {
AutoProcessListLock auto_lock; AutoProcessListLock auto_lock;
for (auto &pw : g_process_list.process_waiters) { for (auto &p : g_process_list.processes) {
Process *p = pw->get_process();
if (kernelAbove200() && p->state >= ProcessState_DebugDetached && p->flags & 0x100) { if (kernelAbove200() && p->state >= ProcessState_DebugDetached && p->flags & 0x100) {
p->flags &= ~0x100; p->flags &= ~0x100;
*out_pid = p->pid; *out_pid = p->pid;
@ -454,13 +451,11 @@ void Registration::GetProcessEventType(u64 *out_pid, u64 *out_type) {
if (kernelAbove500()) { if (kernelAbove500()) {
auto_lock.Unlock(); auto_lock.Unlock();
g_dead_process_list.Lock(); g_dead_process_list.Lock();
if (g_dead_process_list.process_waiters.size()) { if (g_dead_process_list.processes.size()) {
ProcessWaiter *pw = g_dead_process_list.process_waiters[0]; std::shared_ptr<Registration::Process> process = g_dead_process_list.processes[0];
Registration::Process *process = pw->get_process(); g_dead_process_list.processes.erase(g_dead_process_list.processes.begin());
g_dead_process_list.process_waiters.erase(g_dead_process_list.process_waiters.begin());
*out_pid = process->pid; *out_pid = process->pid;
*out_type = 1; *out_type = 1;
delete pw;
g_dead_process_list.Unlock(); g_dead_process_list.Unlock();
return; return;
} }

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <switch.h> #include <switch.h>
#include <stratosphere.hpp> #include <stratosphere.hpp>
#include <memory>
#define LAUNCHFLAGS_NOTIFYWHENEXITED(flags) (flags & 1) #define LAUNCHFLAGS_NOTIFYWHENEXITED(flags) (flags & 1)
#define LAUNCHFLAGS_STARTSUSPENDED(flags) (flags & (kernelAbove500() ? 0x10 : 0x2)) #define LAUNCHFLAGS_STARTSUSPENDED(flags) (flags & (kernelAbove500() ? 0x10 : 0x2))
@ -42,18 +43,18 @@ class Registration {
static void InitializeSystemResources(); static void InitializeSystemResources();
static IWaitable *GetProcessLaunchStartEvent(); static IWaitable *GetProcessLaunchStartEvent();
static void SetProcessListManager(WaitableManager *m);
static Result ProcessLaunchStartCallback(void *arg, Handle *handles, size_t num_handles, u64 timeout); static Result ProcessLaunchStartCallback(void *arg, Handle *handles, size_t num_handles, u64 timeout);
static IWaitable *GetProcessList(); static Result HandleSignaledProcess(std::shared_ptr<Process> process);
static void HandleSignaledProcess(Process *process); static void FinalizeExitedProcess(std::shared_ptr<Process> process);
static void FinalizeExitedProcess(Process *process);
static void AddProcessToList(Process *process); static void AddProcessToList(std::shared_ptr<Process> process);
static void RemoveProcessFromList(u64 pid); static void RemoveProcessFromList(u64 pid);
static void SetProcessState(u64 pid, ProcessState new_state); static void SetProcessState(u64 pid, ProcessState new_state);
static Process *GetProcess(u64 pid); static std::shared_ptr<Registration::Process> GetProcess(u64 pid);
static Process *GetProcessByTitleId(u64 tid); static std::shared_ptr<Registration::Process> GetProcessByTitleId(u64 tid);
static Result GetDebugProcessIds(u64 *out_pids, u32 max_out, u32 *num_out); static Result GetDebugProcessIds(u64 *out_pids, u32 max_out, u32 *num_out);
static Handle GetProcessEventHandle(); static Handle GetProcessEventHandle();
static void GetProcessEventType(u64 *out_pid, u64 *out_type); 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 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 Result LaunchProcessByTidSid(TidSid tid_sid, u64 launch_flags, u64 *out_pid);
static bool HasApplicationProcess(Process **out); static bool HasApplicationProcess(std::shared_ptr<Process> *out);
}; };

View file

@ -92,7 +92,7 @@ std::tuple<Result, u64> ShellService::launch_process(u64 launch_flags, Registrat
std::tuple<Result> ShellService::terminate_process_id(u64 pid) { std::tuple<Result> ShellService::terminate_process_id(u64 pid) {
Registration::AutoProcessListLock auto_lock; Registration::AutoProcessListLock auto_lock;
Registration::Process *proc = Registration::GetProcess(pid); std::shared_ptr<Registration::Process> proc = Registration::GetProcess(pid);
if (proc != NULL) { if (proc != NULL) {
return {svcTerminateProcess(proc->handle)}; return {svcTerminateProcess(proc->handle)};
} else { } else {
@ -103,7 +103,7 @@ std::tuple<Result> ShellService::terminate_process_id(u64 pid) {
std::tuple<Result> ShellService::terminate_title_id(u64 tid) { std::tuple<Result> ShellService::terminate_title_id(u64 tid) {
Registration::AutoProcessListLock auto_lock; Registration::AutoProcessListLock auto_lock;
Registration::Process *proc = Registration::GetProcessByTitleId(tid); std::shared_ptr<Registration::Process> proc = Registration::GetProcessByTitleId(tid);
if (proc != NULL) { if (proc != NULL) {
return {svcTerminateProcess(proc->handle)}; return {svcTerminateProcess(proc->handle)};
} else { } else {
@ -124,7 +124,7 @@ std::tuple<Result, u64, u64> ShellService::get_process_event_type() {
std::tuple<Result> ShellService::finalize_exited_process(u64 pid) { std::tuple<Result> ShellService::finalize_exited_process(u64 pid) {
Registration::AutoProcessListLock auto_lock; Registration::AutoProcessListLock auto_lock;
Registration::Process *proc = Registration::GetProcess(pid); std::shared_ptr<Registration::Process> proc = Registration::GetProcess(pid);
if (proc == NULL) { if (proc == NULL) {
return {0x20F}; return {0x20F};
} else if (proc->state != ProcessState_Exited) { } else if (proc->state != ProcessState_Exited) {
@ -138,7 +138,7 @@ std::tuple<Result> ShellService::finalize_exited_process(u64 pid) {
std::tuple<Result> ShellService::clear_process_notification_flag(u64 pid) { std::tuple<Result> ShellService::clear_process_notification_flag(u64 pid) {
Registration::AutoProcessListLock auto_lock; Registration::AutoProcessListLock auto_lock;
Registration::Process *proc = Registration::GetProcess(pid); std::shared_ptr<Registration::Process> proc = Registration::GetProcess(pid);
if (proc != NULL) { if (proc != NULL) {
proc->flags &= ~2; proc->flags &= ~2;
return {0x0}; return {0x0};
@ -159,7 +159,7 @@ std::tuple<Result> ShellService::notify_boot_finished() {
std::tuple<Result, u64> ShellService::get_application_process_id() { std::tuple<Result, u64> ShellService::get_application_process_id() {
Registration::AutoProcessListLock auto_lock; Registration::AutoProcessListLock auto_lock;
Registration::Process *app_proc; std::shared_ptr<Registration::Process> app_proc;
if (Registration::HasApplicationProcess(&app_proc)) { if (Registration::HasApplicationProcess(&app_proc)) {
return {0, app_proc->pid}; return {0, app_proc->pid};
} }