Skip to content

Commit

Permalink
[Matter.framework] Prevent a leak when using the _subscriptionPoolWor… (
Browse files Browse the repository at this point in the history
  • Loading branch information
vivien-apple authored Oct 9, 2024
1 parent a854245 commit af3727b
Showing 1 changed file with 9 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/darwin/Framework/CHIP/MTRDevice_Concrete.mm
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,9 @@ - (void)_ensureSubscriptionForExistingDelegates:(NSString *)reason
}
if ([self _deviceUsesThread]) {
MTR_LOG(" => %@ - device is a thread device, scheduling in pool", self);
mtr_weakify(self);
[self _scheduleSubscriptionPoolWork:^{
mtr_strongify(self);
[self->_deviceController asyncDispatchToMatterQueue:^{
std::lock_guard lock(self->_lock);
[self _setupSubscriptionWithReason:[NSString stringWithFormat:@"%@ and scheduled subscription is happening", reason]];
Expand Down Expand Up @@ -1165,10 +1167,13 @@ - (void)_scheduleSubscriptionPoolWork:(dispatch_block_t)workBlock inNanoseconds:
return;
}

mtr_weakify(self);
dispatch_block_t workBlockToQueue = ^{
mtr_strongify(self);
// In the case where a resubscription triggering event happened and already established, running the work block should result in a no-op
MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.queue];
[workItem setReadyHandler:^(id _Nonnull context, NSInteger retryCount, MTRAsyncWorkCompletionBlock _Nonnull completion) {
mtr_strongify(self);
MTR_LOG("%@ - work item is ready to attempt pooled subscription", self);
os_unfair_lock_lock(&self->_lock);
#ifdef DEBUG
Expand Down Expand Up @@ -1246,7 +1251,9 @@ - (void)_handleResubscriptionNeededWithDelayOnDeviceQueue:(NSNumber *)resubscrip

// Use the existing _triggerResubscribeWithReason mechanism, which does the right checks when
// this block is run -- if other triggering events had happened, this would become a no-op.
mtr_weakify(self);
auto resubscriptionBlock = ^{
mtr_strongify(self);
[self->_deviceController asyncDispatchToMatterQueue:^{
[self _triggerResubscribeWithReason:@"ResubscriptionNeeded timer fired" nodeLikelyReachable:NO];
} errorHandler:^(NSError * _Nonnull error) {
Expand Down Expand Up @@ -1357,7 +1364,9 @@ - (void)_doHandleSubscriptionReset:(NSNumber * _Nullable)retryDelay

// Call _reattemptSubscriptionNowIfNeededWithReason when timer fires - if subscription is
// in a better state at that time this will be a no-op.
mtr_weakify(self);
auto resubscriptionBlock = ^{
mtr_strongify(self);
[self->_deviceController asyncDispatchToMatterQueue:^{
std::lock_guard lock(self->_lock);
[self _reattemptSubscriptionNowIfNeededWithReason:@"got subscription reset"];
Expand Down

0 comments on commit af3727b

Please sign in to comment.