Skip to content

Commit

Permalink
[Darwin] MTRDevice_XPC delegate callbacks need to hold lock before _c…
Browse files Browse the repository at this point in the history
…allDelegatesWithBlock (project-chip#35095)

* [Darwin] MTRDevice_XPC delegate callbacks need to hold lock before _callDelegatesWithBlock

* Add back _callDelegatesWithBlock to avoid conflict
  • Loading branch information
jtung-apple authored and PeterC1965 committed Aug 28, 2024
1 parent 09a606e commit 2e3bc4e
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 6 deletions.
6 changes: 6 additions & 0 deletions src/darwin/Framework/CHIP/MTRDevice.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,12 @@ - (BOOL)_callDelegatesWithBlock:(void (^)(id<MTRDeviceDelegate> delegate))block
return (delegatesCalled > 0);
}

- (BOOL)_lockAndCallDelegatesWithBlock:(void (^)(id<MTRDeviceDelegate> delegate))block
{
std::lock_guard lock(self->_lock);
return [self _callDelegatesWithBlock:block];
}

#ifdef DEBUG
// Only used for unit test purposes - normal delegate should not expect or handle being called back synchronously
- (void)_callFirstDelegateSynchronouslyWithBlock:(void (^)(id<MTRDeviceDelegate> delegate))block
Expand Down
3 changes: 3 additions & 0 deletions src/darwin/Framework/CHIP/MTRDevice_Internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ MTR_DIRECT_MEMBERS

- (BOOL)_callDelegatesWithBlock:(void (^)(id<MTRDeviceDelegate> delegate))block;

// Called by MTRDevice_XPC to forward delegate callbacks
- (BOOL)_lockAndCallDelegatesWithBlock:(void (^)(id<MTRDeviceDelegate> delegate))block;

/**
* Like the public invokeCommandWithEndpointID but:
*
Expand Down
12 changes: 6 additions & 6 deletions src/darwin/Framework/CHIP/MTRDevice_XPC.mm
Original file line number Diff line number Diff line change
Expand Up @@ -99,23 +99,23 @@ - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControlle
- (oneway void)device:(NSNumber *)nodeID stateChanged:(MTRDeviceState)state
{
MTR_LOG("%s", __PRETTY_FUNCTION__);
[self _callDelegatesWithBlock:^(id<MTRDeviceDelegate> delegate) {
[self _lockAndCallDelegatesWithBlock:^(id<MTRDeviceDelegate> delegate) {
[delegate device:self stateChanged:state];
}];
}

- (oneway void)device:(NSNumber *)nodeID receivedAttributeReport:(NSArray<NSDictionary<NSString *, id> *> *)attributeReport
{
MTR_LOG("%s", __PRETTY_FUNCTION__);
[self _callDelegatesWithBlock:^(id<MTRDeviceDelegate> delegate) {
[self _lockAndCallDelegatesWithBlock:^(id<MTRDeviceDelegate> delegate) {
[delegate device:self receivedAttributeReport:attributeReport];
}];
}

- (oneway void)device:(NSNumber *)nodeID receivedEventReport:(NSArray<NSDictionary<NSString *, id> *> *)eventReport
{
MTR_LOG("%s", __PRETTY_FUNCTION__);
[self _callDelegatesWithBlock:^(id<MTRDeviceDelegate> delegate) {
[self _lockAndCallDelegatesWithBlock:^(id<MTRDeviceDelegate> delegate) {
[delegate device:self receivedEventReport:eventReport];
}];
}
Expand All @@ -124,7 +124,7 @@ - (oneway void)device:(NSNumber *)nodeID receivedEventReport:(NSArray<NSDictiona
- (oneway void)deviceBecameActive:(NSNumber *)nodeID
{
MTR_LOG("%s", __PRETTY_FUNCTION__);
[self _callDelegatesWithBlock:^(id<MTRDeviceDelegate> delegate) {
[self _lockAndCallDelegatesWithBlock:^(id<MTRDeviceDelegate> delegate) {
if ([delegate respondsToSelector:@selector(deviceBecameActive:)]) {
[delegate deviceBecameActive:self];
}
Expand All @@ -133,7 +133,7 @@ - (oneway void)deviceBecameActive:(NSNumber *)nodeID

- (oneway void)deviceCachePrimed:(NSNumber *)nodeID
{
[self _callDelegatesWithBlock:^(id<MTRDeviceDelegate> delegate) {
[self _lockAndCallDelegatesWithBlock:^(id<MTRDeviceDelegate> delegate) {
if ([delegate respondsToSelector:@selector(deviceCachePrimed:)]) {
[delegate deviceCachePrimed:self];
}
Expand All @@ -142,7 +142,7 @@ - (oneway void)deviceCachePrimed:(NSNumber *)nodeID

- (oneway void)deviceConfigurationChanged:(NSNumber *)nodeID
{
[self _callDelegatesWithBlock:^(id<MTRDeviceDelegate> delegate) {
[self _lockAndCallDelegatesWithBlock:^(id<MTRDeviceDelegate> delegate) {
if ([delegate respondsToSelector:@selector(deviceConfigurationChanged:)]) {
[delegate deviceConfigurationChanged:self];
}
Expand Down

0 comments on commit 2e3bc4e

Please sign in to comment.