sm: fix wait list reentrancy and state on processing loop entry

This commit is contained in:
Michael Scire 2020-12-31 15:53:32 -08:00 committed by SciresM
parent f768e3c8f9
commit 7a9018dc7a
2 changed files with 21 additions and 2 deletions

View File

@ -84,9 +84,14 @@ namespace ams::sm::impl {
return; return;
} }
/* Get and clear the triggered service. */
const auto resumed_service = g_triggered_service;
g_triggered_service = InvalidServiceName;
/* Process all entries. */ /* Process all entries. */
for (auto &entry : g_entries) { for (size_t i = 0; i < util::size(g_entries); /* ... */) {
if (entry.service == g_triggered_service) { auto &entry = g_entries[i];
if (entry.service == resumed_service) {
/* Get the entry's session. */ /* Get the entry's session. */
auto * const session = entry.session; auto * const session = entry.session;
@ -100,8 +105,20 @@ namespace ams::sm::impl {
ProcessRegisterRetry(session); ProcessRegisterRetry(session);
} }
} R_END_TRY_CATCH_WITH_ABORT_UNLESS; } R_END_TRY_CATCH_WITH_ABORT_UNLESS;
/* Handle nested resumes. */
if (g_triggered_service != InvalidServiceName) {
AMS_ABORT_UNLESS(g_triggered_service == resumed_service);
g_triggered_service = InvalidServiceName;
i = 0;
continue;
} }
} }
/* Advance. */
++i;
}
} }
} }

View File

@ -111,6 +111,7 @@ int main(int argc, char **argv)
Handle smm_h; Handle smm_h;
R_ABORT_UNLESS(sm::impl::RegisterServiceForSelf(&smm_h, sm::ServiceName::Encode("sm:m"), 1)); R_ABORT_UNLESS(sm::impl::RegisterServiceForSelf(&smm_h, sm::ServiceName::Encode("sm:m"), 1));
g_server_manager.RegisterServer<sm::impl::IManagerInterface, sm::ManagerService>(smm_h); g_server_manager.RegisterServer<sm::impl::IManagerInterface, sm::ManagerService>(smm_h);
sm::impl::TestAndResume(ResumeImpl);
} }
/*===== ATMOSPHERE EXTENSION =====*/ /*===== ATMOSPHERE EXTENSION =====*/
@ -119,6 +120,7 @@ int main(int argc, char **argv)
Handle smdmnt_h; Handle smdmnt_h;
R_ABORT_UNLESS(sm::impl::RegisterServiceForSelf(&smdmnt_h, sm::ServiceName::Encode("sm:dmnt"), 1)); R_ABORT_UNLESS(sm::impl::RegisterServiceForSelf(&smdmnt_h, sm::ServiceName::Encode("sm:dmnt"), 1));
g_server_manager.RegisterServer<sm::impl::IDebugMonitorInterface, sm::DebugMonitorService>(smdmnt_h); g_server_manager.RegisterServer<sm::impl::IDebugMonitorInterface, sm::DebugMonitorService>(smdmnt_h);
sm::impl::TestAndResume(ResumeImpl);
} }
/*================================*/ /*================================*/