@@ -605,11 +605,23 @@ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams
605
605
MTR_LOG (" Loaded attribute values for %lu nodes from storage for controller uuid %@" , static_cast <unsigned long >(clusterDataByNode.count ), self->_uniqueIdentifier );
606
606
607
607
std::lock_guard lock (self->_deviceMapLock );
608
+ NSMutableArray * deviceList = [NSMutableArray array ];
608
609
for (NSNumber * nodeID in clusterDataByNode) {
609
610
NSDictionary * clusterData = clusterDataByNode[nodeID];
610
611
MTRDevice * device = [self _setupDeviceForNodeID: nodeID prefetchedClusterData: clusterData];
611
612
MTR_LOG (" Loaded %lu cluster data from storage for %@" , static_cast <unsigned long >(clusterData.count ), device);
613
+
614
+ [deviceList addObject: device];
612
615
}
616
+
617
+ #define kSecondsToWaitBeforeAPIClientRetainsMTRDevice 60
618
+ // Keep the devices retained for a while, in case API client doesn't immediately retain them.
619
+ //
620
+ // Note that this is just an optimization to avoid throwing the information away and immediately
621
+ // re-reading it from storage.
622
+ dispatch_after (dispatch_time (DISPATCH_TIME_NOW, (int64_t ) (kSecondsToWaitBeforeAPIClientRetainsMTRDevice * NSEC_PER_SEC)), dispatch_get_main_queue (), ^{
623
+ MTR_LOG (" MTRDeviceController: un-retain devices loaded at startup %lu" , static_cast <unsigned long >(deviceList.count ));
624
+ });
613
625
}];
614
626
}
615
627
@@ -1257,15 +1269,12 @@ - (BOOL)checkIsRunning:(NSError * __autoreleasing *)error
1257
1269
1258
1270
- (void )getSessionForNode : (chip::NodeId)nodeID completion : (MTRInternalDeviceConnectionCallback)completion
1259
1271
{
1260
- // First check if MTRDevice exists from having loaded from storage, or created by a client.
1261
- // Do not use deviceForNodeID here, because we don't want to create the device if it does not already exist.
1262
- os_unfair_lock_lock (&_deviceMapLock);
1263
- MTRDevice * device = [_nodeIDToDeviceMap objectForKey: @(nodeID)];
1264
- os_unfair_lock_unlock (&_deviceMapLock);
1272
+ // Get the corresponding MTRDevice object to determine if the case/subscription pool is to be used
1273
+ MTRDevice * device = [self deviceForNodeID: @(nodeID)];
1265
1274
1266
1275
// In the case that this device is known to use thread, queue this with subscription attempts as well, to
1267
1276
// help with throttling Thread traffic.
1268
- if (device && [device deviceUsesThread ]) {
1277
+ if ([device deviceUsesThread ]) {
1269
1278
MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc ] initWithQueue: dispatch_get_global_queue (QOS_CLASS_DEFAULT , 0 )];
1270
1279
[workItem setReadyHandler: ^(id _Nonnull context, NSInteger retryCount, MTRAsyncWorkCompletionBlock _Nonnull workItemCompletion) {
1271
1280
MTRInternalDeviceConnectionCallback completionWrapper = ^(chip::Messaging::ExchangeManager * _Nullable exchangeManager,
0 commit comments