Skip to content

Commit c19640a

Browse files
Make the state machine naming for MTRDevice match reality better.
Basically covers my post-landing review comments on project-chip#32579
1 parent 04251f1 commit c19640a

File tree

1 file changed

+35
-10
lines changed

1 file changed

+35
-10
lines changed

src/darwin/Framework/CHIP/MTRDevice.mm

+35-10
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
NSString * const MTRPreviousDataKey = @"previousData";
5353
NSString * const MTRDataVersionKey = @"dataVersion";
5454

55-
#define kTimeToWaitBeforeMarkingUnreachableAfterSettingUpSubscription 10
55+
#define kSecondsToWaitBeforeMarkingUnreachableAfterSettingUpSubscription 10
5656

5757
// Consider moving utility classes to their own file
5858
#pragma mark - Utility Classes
@@ -129,11 +129,31 @@ - (id)strongObject
129129

130130
#pragma mark - MTRDevice
131131
typedef NS_ENUM(NSUInteger, MTRInternalDeviceState) {
132+
// Unsubscribed means we do not have a subscription and are not trying to set one up.
132133
MTRInternalDeviceStateUnsubscribed = 0,
134+
// Subscribing means we are actively trying to establish our initial subscription (e.g. doing
135+
// DNS-SD discovery, trying to establish CASE to the peer, getting priming reports, etc).
133136
MTRInternalDeviceStateSubscribing = 1,
134-
MTRInternalDeviceStateSubscribed = 2
137+
// InitialSubscriptionEstablished means we have at some point finished setting up a
138+
// subscription. That subscription may have dropped since then, but if so it's the ReadClient's
139+
// responsibility to re-establish it.
140+
MTRInternalDeviceStateInitalSubscriptionEstablished = 2,
135141
};
136142

143+
// Utility methods for working with MTRInternalDeviceState, located near the
144+
// enum so it's easier to notice that they need to stay in sync.
145+
namespace {
146+
bool NoInitialSubscriptionYet(MTRInternalDeviceState state)
147+
{
148+
return state < MTRInternalDeviceStateInitalSubscriptionEstablished;
149+
}
150+
151+
bool NeedToStartSubscriptionSetup(MTRInternalDeviceState state)
152+
{
153+
return state <= MTRInternalDeviceStateUnsubscribed;
154+
}
155+
} // anonymous namespace
156+
137157
typedef NS_ENUM(NSUInteger, MTRDeviceExpectedValueFieldIndex) {
138158
MTRDeviceExpectedValueFieldExpirationTimeIndex = 0,
139159
MTRDeviceExpectedValueFieldValueIndex = 1,
@@ -283,6 +303,7 @@ - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControlle
283303
_expectedValueCache = [NSMutableDictionary dictionary];
284304
_asyncWorkQueue = [[MTRAsyncWorkQueue alloc] initWithContext:self];
285305
_state = MTRDeviceStateUnknown;
306+
_internalDeviceState = MTRInternalDeviceStateUnsubscribed;
286307
_clusterData = [NSMutableDictionary dictionary];
287308
MTR_LOG_INFO("%@ init with hex nodeID 0x%016llX", self, _nodeID.unsignedLongLongValue);
288309
}
@@ -576,6 +597,10 @@ - (void)invalidate
576597
// attempt, since we now have no delegate.
577598
_reattemptingSubscription = NO;
578599

600+
// We do not change _internalDeviceState here, because we might still have a
601+
// subscription. In that case, _internalDeviceState will update when the
602+
// subscription is actually terminated.
603+
579604
os_unfair_lock_unlock(&self->_lock);
580605
}
581606

@@ -678,7 +703,7 @@ - (void)_handleSubscriptionEstablished
678703

679704
// reset subscription attempt wait time when subscription succeeds
680705
_lastSubscriptionAttemptWait = 0;
681-
_internalDeviceState = MTRInternalDeviceStateSubscribed;
706+
_internalDeviceState = MTRInternalDeviceStateInitalSubscriptionEstablished;
682707

683708
// As subscription is established, check if the delegate needs to be informed
684709
if (!_delegateDeviceCachePrimedCalled) {
@@ -786,12 +811,13 @@ - (void)_handleUnsolicitedMessageFromPublisher
786811
[self _reattemptSubscriptionNowIfNeeded];
787812
}
788813

789-
- (void)_markDeviceAsUnreachableIfNotSusbcribed
814+
- (void)_markDeviceAsUnreachableIfNeverSubscribed
790815
{
791816
os_unfair_lock_assert_owner(&self->_lock);
792817

793-
if (_internalDeviceState >= MTRInternalDeviceStateSubscribed)
818+
if (!NoInitialSubscriptionYet(_internalDeviceState)) {
794819
return;
820+
}
795821

796822
MTR_LOG_DEFAULT("%@ still not subscribed, marking the device as unreachable", self);
797823
[self _changeState:MTRDeviceStateUnreachable];
@@ -1025,20 +1051,19 @@ - (void)_setupSubscription
10251051
#endif
10261052

10271053
// for now just subscribe once
1028-
if (_internalDeviceState > MTRInternalDeviceStateUnsubscribed) {
1054+
if (!NeedToStartSubscriptionSetup(_internalDeviceState)) {
10291055
return;
10301056
}
10311057

10321058
_internalDeviceState = MTRInternalDeviceStateSubscribing;
10331059

10341060
// Set up a timer to mark as not reachable if it takes too long to set up a subscription
10351061
MTRWeakReference<MTRDevice *> * weakSelf = [MTRWeakReference weakReferenceWithObject:self];
1036-
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (kTimeToWaitBeforeMarkingUnreachableAfterSettingUpSubscription * NSEC_PER_SEC)), self.queue, ^{
1062+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, static_cast<int64_t>(kSecondsToWaitBeforeMarkingUnreachableAfterSettingUpSubscription) * static_cast<int64_t>(NSEC_PER_SEC)), self.queue, ^{
10371063
MTRDevice * strongSelf = weakSelf.strongObject;
10381064
if (strongSelf != nil) {
1039-
os_unfair_lock_lock(&strongSelf->_lock);
1040-
[strongSelf _markDeviceAsUnreachableIfNotSusbcribed];
1041-
os_unfair_lock_unlock(&strongSelf->_lock);
1065+
std::lock_guard(strongSelf->_lock);
1066+
[strongSelf _markDeviceAsUnreachableIfNeverSubscribed];
10421067
}
10431068
});
10441069

0 commit comments

Comments
 (0)