diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm index d0040a2caf54ba..885b118a31cc65 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm @@ -44,6 +44,8 @@ #include #include +#include + using namespace chip; using namespace chip::Controller; @@ -58,6 +60,9 @@ static NSString * const kErrorCDCertStoreInit = @"Init failure while initializing Certificate Declaration Signing Keys store"; static NSString * const kErrorOtaProviderInit = @"Init failure while creating an OTA provider delegate"; +static bool sExitHandlerRegistered = false; +static void ShutdownOnExit() { [[MTRDeviceControllerFactory sharedInstance] stopControllerFactory]; } + @interface MTRDeviceControllerFactory () @property (atomic, readonly) dispatch_queue_t chipWorkQueue; @@ -382,7 +387,14 @@ - (BOOL)startControllerFactory:(MTRDeviceControllerFactoryParams *)startupParams // This needs to happen after DeviceControllerFactory::Init, // because that creates (lazily, by calling functions with // static variables in them) some static-lifetime objects. - chip::HeapObjectPoolExitHandling::IgnoreLeaksOnExit(); + if (!sExitHandlerRegistered) { + int ret = atexit(ShutdownOnExit); + if (ret != 0) { + MTR_LOG_ERROR("Error registering exit handler: %d", ret); + return; + } + } + HeapObjectPoolExitHandling::IgnoreLeaksOnExit(); // Make sure we don't leave a system state running while we have no // controllers started. This is working around the fact that a system