pm: fix busy loop on <5.0.0 when processes exit

This was caused by failing to unlink exited processes from the
waitable list, so the process manager thread would loop forever on the
same process signal.
This commit is contained in:
misson20000 2019-12-13 12:58:28 -08:00
parent f9a199557c
commit d72191ed5f
3 changed files with 14 additions and 1 deletions

View File

@ -37,7 +37,7 @@ namespace ams::pm::impl {
this->handle = INVALID_HANDLE;
/* Unlink the process from its waitable manager. */
this->waitable_holder.UnlinkFromWaitableManager();
UnlinkFromWaitableManagerIfLinked();
}
}

View File

@ -46,6 +46,7 @@ namespace ams::pm::impl {
ProcessState state;
u32 flags;
os::WaitableHolder waitable_holder;
bool waitable_holder_is_linked = false;
private:
void SetFlag(Flag flag) {
this->flags |= flag;
@ -64,7 +65,16 @@ namespace ams::pm::impl {
void Cleanup();
void LinkToWaitableManager(os::WaitableManager &manager) {
AMS_ASSERT(!waitable_holder_is_linked);
manager.LinkWaitableHolder(&this->waitable_holder);
waitable_holder_is_linked = true;
}
void UnlinkFromWaitableManagerIfLinked() {
if (waitable_holder_is_linked) {
this->waitable_holder.UnlinkFromWaitableManager();
waitable_holder_is_linked = false;
}
}
Handle GetHandle() const {

View File

@ -414,6 +414,8 @@ namespace ams::pm::impl {
case ProcessState_Exited:
if (hos::GetVersion() < hos::Version_500 && process_info->ShouldSignalOnExit()) {
g_process_event.Signal();
process_info->UnlinkFromWaitableManagerIfLinked();
} else {
/* Free process resources, unlink from waitable manager. */
process_info->Cleanup();
@ -436,6 +438,7 @@ namespace ams::pm::impl {
CleanupProcessInfo(list, process_info);
}
}
break;
case ProcessState_DebugSuspended:
if (process_info->ShouldSignalOnDebugEvent()) {
process_info->SetSuspended();