From 54d2f16c22ca8294c3c8777b2216428a0e9d7f25 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Tue, 12 Mar 2019 19:06:20 -0400 Subject: [PATCH 1/2] core: reset kernel after service manager in Shutdown Services can hold kernel objects and do cleanup upon destruction, so we need to keep the kernel alive longer. The new order approximnately resembles the reverse construction order. I will revisit the ordering issue and make it less error-prone after global state cleanup --- src/core/core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 9473b5c0cb..d48f0c8ecf 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -291,7 +291,6 @@ void System::Shutdown() { // Shutdown emulation session GDBStub::Shutdown(); VideoCore::Shutdown(); - kernel.reset(); HW::Shutdown(); telemetry_session.reset(); rpc_server.reset(); @@ -299,6 +298,7 @@ void System::Shutdown() { service_manager.reset(); dsp_core.reset(); cpu_core.reset(); + kernel.reset(); timing.reset(); app_loader.reset(); From 8750b81ce0ce7e2f6c9ee45634bb832af9e9dde4 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Tue, 12 Mar 2019 19:11:46 -0400 Subject: [PATCH 2/2] ServiceFrameworkBase: remove ownership to ServerPort This causes a reference cycle because ServerPort also holds a shared pointer to SessionRequestHandler (inherited by ServiceFrameworkBase). Given that the member port is never used in ServiceFrameworkBase, we can simply remove it. The port object is kept alive by ServiceManager|KernelSystem::named_ports -> ClientPort -> ServerPort --- src/core/hle/service/service.cpp | 4 +--- src/core/hle/service/service.h | 6 ------ 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 3eb4dfcaa1..19333fd01a 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -131,13 +131,11 @@ ServiceFrameworkBase::ServiceFrameworkBase(const char* service_name, u32 max_ses ServiceFrameworkBase::~ServiceFrameworkBase() = default; void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager) { - ASSERT(port == nullptr); - port = service_manager.RegisterService(service_name, max_sessions).Unwrap(); + auto port = service_manager.RegisterService(service_name, max_sessions).Unwrap(); port->SetHleHandler(shared_from_this()); } void ServiceFrameworkBase::InstallAsNamedPort(Kernel::KernelSystem& kernel) { - ASSERT(port == nullptr); auto [server_port, client_port] = kernel.CreatePortPair(max_sessions, service_name); server_port->SetHleHandler(shared_from_this()); kernel.AddNamedPort(service_name, std::move(client_port)); diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 4aa1cb6001..c44249000f 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -92,12 +92,6 @@ private: /// Maximum number of concurrent sessions that this service can handle. u32 max_sessions; - /** - * Port where incoming connections will be received. Only created when InstallAsService() or - * InstallAsNamedPort() are called. - */ - Kernel::SharedPtr port; - /// Function used to safely up-cast pointers to the derived class before invoking a handler. InvokerFn* handler_invoker; boost::container::flat_map handlers;