Darwin: Refactor stack startup logic when creating a controller (#32845)
* Darwin: Don't stop/start the stack when creating a controller
* Keep refactorings in place but retain current behavior for now
* Darwin: Enable CHIP_CONFIG_GLOBALS_NO_DESTRUCT=1
This was missed in #32745 when adding -fno-c++-static-destructors, since that
flag does not carry through to lazily initialized chip::Global instances.
diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm
index 22d52cd..961b6f8 100644
--- a/src/darwin/Framework/CHIP/MTRDeviceController.mm
+++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm
@@ -139,25 +139,15 @@
{
if (![parameters isKindOfClass:MTRDeviceControllerParameters.class]) {
MTR_LOG_ERROR("Unsupported type of MTRDeviceControllerAbstractParameters: %@", parameters);
-
if (error) {
*error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT];
}
return nil;
}
+ auto * controllerParameters = static_cast<MTRDeviceControllerParameters *>(parameters);
- __auto_type * factory = [MTRDeviceControllerFactory sharedInstance];
- if (!factory.isRunning) {
- auto * params = [[MTRDeviceControllerFactoryParams alloc] initWithoutStorage];
-
- if (![factory startControllerFactory:params error:error]) {
- return nil;
- }
- }
-
- auto * parametersForFactory = static_cast<MTRDeviceControllerParameters *>(parameters);
-
- return [factory initializeController:self withParameters:parametersForFactory error:error];
+ // MTRDeviceControllerFactory will auto-start in per-controller-storage mode if necessary
+ return [MTRDeviceControllerFactory.sharedInstance initializeController:self withParameters:controllerParameters error:error];
}
- (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory
diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm
index 5941a79..b31003c 100644
--- a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm
+++ b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm
@@ -417,7 +417,14 @@
return [NSArray arrayWithArray:fabricList];
}
-- (BOOL)startControllerFactory:(MTRDeviceControllerFactoryParams *)startupParams error:(NSError * __autoreleasing *)error;
+- (BOOL)startControllerFactory:(MTRDeviceControllerFactoryParams *)startupParams error:(NSError * __autoreleasing *)error
+{
+ return [self _startControllerFactory:startupParams startingController:NO error:error];
+}
+
+- (BOOL)_startControllerFactory:(MTRDeviceControllerFactoryParams *)startupParams
+ startingController:(BOOL)startingController
+ error:(NSError * __autoreleasing *)error
{
[self _assertCurrentQueueIsNotMatterQueue];
@@ -535,6 +542,7 @@
// state is brought up live on factory init, and not when it comes time
// to actually start a controller, and does not actually clean itself up
// until its refcount (which starts as 0) goes to 0.
+ // TODO: Don't cause a stack shutdown and restart if startingController
_controllerFactory->RetainSystemState();
_controllerFactory->ReleaseSystemState();
@@ -597,11 +605,6 @@
{
[self _assertCurrentQueueIsNotMatterQueue];
- if (![self checkIsRunning:error]) {
- MTR_LOG_ERROR("Trying to start controller while Matter controller factory is not running");
- return nil;
- }
-
id<MTRDeviceControllerStorageDelegate> _Nullable storageDelegate;
dispatch_queue_t _Nullable storageDelegateQueue;
NSUUID * uniqueIdentifier;
@@ -623,9 +626,28 @@
otaProviderDelegateQueue = nil;
} else {
MTR_LOG_ERROR("Unknown kind of startup params: %@", startupParams);
+ if (error != nil) {
+ *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT];
+ }
return nil;
}
+ if (![self isRunning]) {
+ if (storageDelegate != nil) {
+ MTR_LOG_DEFAULT("Auto-starting Matter controller factory in per-controller storage mode");
+ auto * params = [[MTRDeviceControllerFactoryParams alloc] initWithoutStorage];
+ if (![self _startControllerFactory:params startingController:YES error:error]) {
+ return nil;
+ }
+ } else {
+ MTR_LOG_ERROR("Trying to start controller while Matter controller factory is not running");
+ if (error != nil) {
+ *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE];
+ }
+ return nil;
+ }
+ }
+
if (_usingPerControllerStorage && storageDelegate == nil) {
MTR_LOG_ERROR("Must have a controller storage delegate when we do not have storage for the controller factory");
if (error != nil) {
diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj
index 1e54062..80c451c 100644
--- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj
+++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj
@@ -2256,6 +2256,7 @@
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-fno-c++-static-destructors",
+ "-DCHIP_CONFIG_GLOBALS_NO_DESTRUCT=1",
);
OTHER_LDFLAGS = "";
"OTHER_LDFLAGS[sdk=*]" = (
@@ -2421,6 +2422,7 @@
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-fno-c++-static-destructors",
+ "-DCHIP_CONFIG_GLOBALS_NO_DESTRUCT=1",
);
OTHER_LDFLAGS = "";
"OTHER_LDFLAGS[sdk=*]" = (