From cbabb80ef4465d5420a2248e1cfa456a6c96eed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Antonio=20Hern=C3=A1ndez=20C=C3=A1novas?= Date: Tue, 21 Aug 2018 21:52:15 +0200 Subject: [PATCH 1/4] added guards for svcWaitSynchronization; added unhandled result code when invalid handle --- .../source/waitablemanager.cpp | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/stratosphere/libstratosphere/source/waitablemanager.cpp b/stratosphere/libstratosphere/source/waitablemanager.cpp index 615bf861d..513d0db84 100644 --- a/stratosphere/libstratosphere/source/waitablemanager.cpp +++ b/stratosphere/libstratosphere/source/waitablemanager.cpp @@ -35,7 +35,12 @@ void WaitableManager::process_internal(bool break_on_timeout) { handles.resize(this->waitables.size()); std::transform(this->waitables.begin(), this->waitables.end(), handles.begin(), [](IWaitable *w) { return w->get_handle(); }); - + if(this->waitables.size() == 0) { + continue; + } + if(this->waitables.size() > 0x40) { + panic("PANIC: Too many waitables in waitablemanager"); + } rc = svcWaitSynchronization(&handle_index, handles.data(), this->waitables.size(), this->timeout); if (R_SUCCEEDED(rc)) { /* Handle a signaled waitable. */ @@ -50,8 +55,25 @@ void WaitableManager::process_internal(bool break_on_timeout) { if (break_on_timeout) { return; } + } else if (rc == 0xE401) { + /* Invalid handle */ + /* handle_index does not get updated when this happens + so we can't really do anything */ + panic("PANIC: Invalid handle in waitablemanager"); + + /* however switchbrew says that svcWaitSynchronization + does not accept 0xFFFF8001 or 0xFFFF8000 as handles + so we could at least remove them if any exists + + for(auto it = waitables.begin(); it != waitables.end(); it++) { + if(*it->get_handle() == 0xFFFF8000 || *it->get_handle() == 0xFFFF8001) { + waitables.erase(it); + } + } + */ } else if (rc != 0xF601) { - /* TODO: Panic. When can this happen? */ + /* TODO: When can this happen? */ + panic("PANIC: unhandled result code in waitablemanager"); } if (rc == 0xF601) { From 385d92fecbd81bc019a46ff4b3428c1c39048813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Antonio=20Hern=C3=A1ndez=20C=C3=A1novas?= Date: Tue, 21 Aug 2018 22:07:18 +0200 Subject: [PATCH 2/4] corrected panics because not implemented --- .../libstratosphere/source/waitablemanager.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/stratosphere/libstratosphere/source/waitablemanager.cpp b/stratosphere/libstratosphere/source/waitablemanager.cpp index 513d0db84..cac2e42c7 100644 --- a/stratosphere/libstratosphere/source/waitablemanager.cpp +++ b/stratosphere/libstratosphere/source/waitablemanager.cpp @@ -39,7 +39,7 @@ void WaitableManager::process_internal(bool break_on_timeout) { continue; } if(this->waitables.size() > 0x40) { - panic("PANIC: Too many waitables in waitablemanager"); + /* TODO: panic. Too many waitables */ } rc = svcWaitSynchronization(&handle_index, handles.data(), this->waitables.size(), this->timeout); if (R_SUCCEEDED(rc)) { @@ -58,22 +58,18 @@ void WaitableManager::process_internal(bool break_on_timeout) { } else if (rc == 0xE401) { /* Invalid handle */ /* handle_index does not get updated when this happens - so we can't really do anything */ - panic("PANIC: Invalid handle in waitablemanager"); - - /* however switchbrew says that svcWaitSynchronization + so we don't know which waitable is the problem. + However switchbrew says that svcWaitSynchronization does not accept 0xFFFF8001 or 0xFFFF8000 as handles - so we could at least remove them if any exists + so we could at least remove them if any exists */ for(auto it = waitables.begin(); it != waitables.end(); it++) { if(*it->get_handle() == 0xFFFF8000 || *it->get_handle() == 0xFFFF8001) { waitables.erase(it); } } - */ } else if (rc != 0xF601) { - /* TODO: When can this happen? */ - panic("PANIC: unhandled result code in waitablemanager"); + /* TODO: panic. When can this happen? */ } if (rc == 0xF601) { From 6dbe3cf4f1fd8f0c472d60eb2e4ba065abe47a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Antonio=20Hern=C3=A1ndez=20C=C3=A1novas?= Date: Tue, 21 Aug 2018 22:08:29 +0200 Subject: [PATCH 3/4] operator precedence --- stratosphere/libstratosphere/source/waitablemanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stratosphere/libstratosphere/source/waitablemanager.cpp b/stratosphere/libstratosphere/source/waitablemanager.cpp index cac2e42c7..10b82330a 100644 --- a/stratosphere/libstratosphere/source/waitablemanager.cpp +++ b/stratosphere/libstratosphere/source/waitablemanager.cpp @@ -64,7 +64,7 @@ void WaitableManager::process_internal(bool break_on_timeout) { so we could at least remove them if any exists */ for(auto it = waitables.begin(); it != waitables.end(); it++) { - if(*it->get_handle() == 0xFFFF8000 || *it->get_handle() == 0xFFFF8001) { + if((*it)->get_handle() == 0xFFFF8000 || (*it)->get_handle() == 0xFFFF8001) { waitables.erase(it); } } From 46cd7e88479bd0bdb27e50132ea9a192f652cdc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Antonio=20Hern=C3=A1ndez=20C=C3=A1novas?= Date: Tue, 21 Aug 2018 22:13:04 +0200 Subject: [PATCH 4/4] same for multithreadedwaitablemanager --- .../source/multithreadedwaitablemanager.cpp | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/stratosphere/libstratosphere/source/multithreadedwaitablemanager.cpp b/stratosphere/libstratosphere/source/multithreadedwaitablemanager.cpp index 4d1dbfaec..8c3dc118a 100644 --- a/stratosphere/libstratosphere/source/multithreadedwaitablemanager.cpp +++ b/stratosphere/libstratosphere/source/multithreadedwaitablemanager.cpp @@ -42,6 +42,12 @@ IWaitable *MultiThreadedWaitableManager::get_waitable() { handles.resize(this->waitables.size()); std::transform(this->waitables.begin(), this->waitables.end(), handles.begin(), [](IWaitable *w) { return w->get_handle(); }); + if(this->waitables.size() == 0) { + continue; + } + if(this->waitables.size() > 0x40) { + /* TODO: panic. Too many waitables */ + } rc = svcWaitSynchronization(&handle_index, handles.data(), this->waitables.size(), this->timeout); IWaitable *w = this->waitables[handle_index]; if (R_SUCCEEDED(rc)) { @@ -50,7 +56,20 @@ IWaitable *MultiThreadedWaitableManager::get_waitable() { } else if (rc == 0xEA01) { /* Timeout. */ std::for_each(waitables.begin(), waitables.end(), std::mem_fn(&IWaitable::update_priority)); - } else if (rc != 0xF601 && rc != 0xE401) { + } else if (rc == 0xE401) { + /* Invalid handle */ + /* handle_index does not get updated when this happens + so we don't know which waitable is the problem. + However switchbrew says that svcWaitSynchronization + does not accept 0xFFFF8001 or 0xFFFF8000 as handles + so we could at least remove them if any exists */ + + for(auto it = waitables.begin(); it != waitables.end(); it++) { + if((*it)->get_handle() == 0xFFFF8000 || (*it)->get_handle() == 0xFFFF8001) { + waitables.erase(it); + } + } + } else if (rc != 0xF601) { /* TODO: Panic. When can this happen? */ } else { std::for_each(waitables.begin(), waitables.begin() + handle_index, std::mem_fn(&IWaitable::update_priority));