diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm index cf4ab4c068d465..21ec9e56f737e9 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm @@ -163,11 +163,17 @@ - (void)cleanupAfterStartup { // Invalidate our MTRDevice instances before we shut down our secure // sessions and whatnot, so they don't start trying to resubscribe when we - // do the secure session shutdowns. - for (MTRDevice * device in [self.nodeIDToDeviceMap allValues]) { + // do the secure session shutdowns. Since we don't want to hold the lock + // while calling out into arbitrary invalidation code, snapshot the list of + // devices before we start invalidating. + os_unfair_lock_lock(&_deviceMapLock); + NSArray * devices = [self.nodeIDToDeviceMap allValues]; + [self.nodeIDToDeviceMap removeAllObjects]; + os_unfair_lock_unlock(&_deviceMapLock); + + for (MTRDevice * device in devices) { [device invalidate]; } - [self.nodeIDToDeviceMap removeAllObjects]; [self stopBrowseForCommissionables]; [_factory controllerShuttingDown:self];