diff --git a/src/darwin/Framework/CHIP/MTRAsyncCallbackWorkQueue.mm b/src/darwin/Framework/CHIP/MTRAsyncCallbackWorkQueue.mm index ad6900a001f41e..ece651a21238de 100644 --- a/src/darwin/Framework/CHIP/MTRAsyncCallbackWorkQueue.mm +++ b/src/darwin/Framework/CHIP/MTRAsyncCallbackWorkQueue.mm @@ -47,7 +47,7 @@ @interface MTRAsyncCallbackQueueWorkItem () @property (nonatomic, strong) MTRAsyncCallbackWorkQueue * workQueue; @property (nonatomic, readonly) BOOL enqueued; // Called by the queue -- (void)markedEnqueued; +- (void)markEnqueued; - (void)callReadyHandlerWithContext:(id)context; - (void)cancel; @end @@ -85,7 +85,7 @@ - (void)enqueueWorkItem:(MTRAsyncCallbackQueueWorkItem *)item return; } - [item markedEnqueued]; + [item markEnqueued]; os_unfair_lock_lock(&_lock); item.workQueue = self; @@ -204,7 +204,7 @@ - (void)invalidate os_unfair_lock_unlock(&_lock); } -- (void)markedEnqueued +- (void)markEnqueued { os_unfair_lock_lock(&_lock); _enqueued = YES; diff --git a/src/darwin/Framework/CHIP/MTRAsyncWorkQueue.h b/src/darwin/Framework/CHIP/MTRAsyncWorkQueue.h index 259bf1dbc78a25..5bc302c6e39714 100644 --- a/src/darwin/Framework/CHIP/MTRAsyncWorkQueue.h +++ b/src/darwin/Framework/CHIP/MTRAsyncWorkQueue.h @@ -19,66 +19,187 @@ NS_ASSUME_NONNULL_BEGIN -@class MTRAsyncWorkItem; - -typedef void (^MTRAsyncWorkReadyHandler)(id context, NSUInteger retryCount); - -// MTRAsyncWorkQueue high level description -// The MTRAsyncWorkQueue was made to call one readyHandler -// block at a time asynchronously, and the readyHandler is -// expected to start/schedule a task. When the task finishes -// asynchronously in the future (at any time, from any queue -// or thread), it is expected to ask the workItem object to -// either endWork or retryWork. - -// Sequence of steps when queuing a work item: -// - Create MTRAsyncWorkItem object -// - Create ready handler block (MTRAsyncWorkReadyHandler) -// - block is called when it's the WorkItem's turn to do work -// - its body is to perform a task that is expected to end asynchronously in the future -// - at the end of work, call on the work item object: -// - endWork for success or failure -// - retryWork for temporary failures -// - Set the readyHandler block on the WorkItem object -// - Call enqueueWorkItem on a MTRAsyncWorkQueue - -// A serial one-at-a-time queue for performing work items +typedef NS_ENUM(NSInteger, MTRAsyncWorkOutcome) { + MTRAsyncWorkComplete, + MTRAsyncWorkNeedsRetry, +}; + +/// The type of completion handler passed to `MTRAsyncWorkItem`. +/// Return YES if the completion call was valid, or NO if the +/// work item was already completed previously (e.g. due to +/// being cancelled). +typedef BOOL (^MTRAsyncWorkCompletionBlock)(MTRAsyncWorkOutcome outcome); + +/// An optional handler that controls batching of MTRAsyncWorkItem. +/// +/// When a work item is dequeued to run, if it is of a type that can be +/// combined with similar work items in a batch, this facility provides an +/// opportunity to coalesce and merge work items. +/// +/// The batching handler is called by the work queue when all of the following +/// are true: +/// 1) A work item that is batchable is about to be executed for the first time +/// 2) The next work item in the queue is also batchable +/// 3) The two work items have identical batching ids +/// +/// The handler will be passed the opaque data of the two work items: +/// `opaqueDataCurrent` is the data of the item about to be executed and +/// `opaqueDataNext` is the data for the next item. The `fullyMerged` parameter +/// will be initialized to NO by the caller. +/// +/// The handler is expected to mutate the data as needed to achieve batching. +/// +/// If after the data mutations opaqueDataNext no longer requires any work, the +/// handler should set `fullyMerged` to YES to indicate that the next item can +/// be dropped from the queue. In this case, the handler may be called again to +/// possibly also batch the work item after the one that was dropped. +/// +/// @see MTRAsyncWorkItem +typedef void (^MTRAsyncWorkBatchingHandler)(id opaqueDataCurrent, id opaqueDataNext, BOOL * fullyMerged); + +/// An optional handler than enables duplicate checking for MTRAsyncWorkItem. +/// +/// The duplicate check handler is called when the client wishes to check +/// whether a new candidate work item is a duplicate of an existing queued +/// item, so that the client may decide to not enqueue the duplicate work. +/// Duplicate checking is performed in reverse queue order, i.e. more +/// recently enqueued items will be checked first. +/// +/// The handler will be passed the opaque data of the candidate work item. The +/// `stop` and `isDuplicate` parameters will be initialized to NO by the caller. +/// +/// If the handler determines the data is indeed duplicate work, it should +/// set `stop` to YES, and set `isDuplicate` to YES. +/// +/// If the handler determines the data is not duplicate work, it should set +/// `stop` to YES, and set `isDuplicate` to NO. +/// +/// If the handler is unable to determine if the data is duplicate work, it +/// should set `stop` to NO; the value of `isDuplicate` will be ignored. +/// +/// @see MTRAsyncWorkItem +typedef void (^MTRAsyncWorkDuplicateCheckHandler)(id opaqueItemData, BOOL * isDuplicate, BOOL * stop); + +/// A unit of work that can be run on a `MTRAsyncWorkQueue`. +/// +/// A work item can be configured with a number of hander blocks called by the +/// async work queue in various situations. Generally work items will have at +/// least a `readyHandler` (though it is technically optional). +/// +/// This class is not thread-safe, and once a work item has been submitted to +/// the queue via `enqueueWorkItem` ownership of the work item passes to the +/// queue. No further modifications may be made to it after that point. +/// +/// @see -[MTRAsyncWorkQueue enqueueWorkItem:] MTR_TESTABLE -@interface MTRAsyncWorkQueue : NSObject +@interface MTRAsyncWorkItem<__contravariant ContextType> : NSObject + - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; -// The context object is only held and passed back as a reference and is opaque to the work queue -- (instancetype)initWithContext:(id _Nullable)context queue:(dispatch_queue_t)queue; +/// Creates a work item that will run on the specified dispatch queue. +- (instancetype)initWithQueue:(dispatch_queue_t)queue; -// Called by the work queue owner to clean up and cancel work items -- (void)invalidate; +/// Called by the work queue to start this work item. +/// +/// Will be called on the dispatch queue associated with this item. +/// +/// This handler block must, synchronously or asynchronously from any thread, +/// call the provided completion block exactly once. Passing an outcome of +/// MTRAsyncWorkComplete removes it from the queue and allows the queue to move +/// on to the next work item (if any). +/// +/// Passing an outcome of MTRAsyncWorkNeedsRetry causes the queue to start the +/// work item again with an incremented retryCount. The retryCount is 0 when a +/// work item is executed for the first time. +@property (nonatomic, strong, nullable) void (^readyHandler) + (ContextType context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion); + +/// Called by the work queue to cancel the work item. +/// +/// Will be called on the dispatch queue associated with this item. +/// The work item may or may not have been started already. +@property (nonatomic, strong, nullable) void (^cancelHandler)(void); + +@property (nonatomic, readonly) NSUInteger batchingID; +@property (nonatomic, readonly, nullable) id batchableData; +@property (nonatomic, readonly, nullable) MTRAsyncWorkBatchingHandler batchingHandler; + +/// Sets the batching handler and associated data for this work item. +/// +/// Note: This handler is NOT called on the dispatch queue associated with +/// this work item. Thread-safety is managed by the work queue internally. +/// +/// If no `batchingHandler` is set using this method, the work item will not +/// participate in batching, and the `batchingID` and `batchableData` +/// properties are meaningless. +/// +/// @see MTRAsyncWorkBatchingHandler +- (void)setBatchingID:(NSUInteger)opaqueBatchingID + data:(id)opaqueBatchableData + handler:(MTRAsyncWorkBatchingHandler)batchingHandler; + +@property (nonatomic, readonly) NSUInteger duplicateTypeID; +@property (nonatomic, readonly, nullable) MTRAsyncWorkDuplicateCheckHandler duplicateCheckHandler; + +/// Sets the duplicate check type and handler for this work item. +/// +/// Note: This handler is NOT called on the dispatch queue associated with +/// this work item. Thread-safety is managed by the work queue internally. +/// +/// If no `duplicateCheckHandler` is set using this method, the work item +/// will not participate in duplicate checking, and the `duplicateTypeID` +/// property is meaningless. +/// +/// @see MTRAsyncWorkDuplicateCheckHandler +- (void)setDuplicateTypeID:(NSUInteger)opaqueDuplicateTypeID + handler:(MTRAsyncWorkDuplicateCheckHandler)duplicateCheckHandler; -// Work items may be enqueued from any queue or thread -// Note: Once a work item is enqueued, its handlers cannot be modified -- (void)enqueueWorkItem:(MTRAsyncWorkItem *)item; @end -// An item in the work queue +/// A serial one-at-a-time queue for performing asynchronous work items. +/// +/// Units of work are represented by MTRAsyncWorkItem objects that are +/// configured with one or more handler blocks before being passed to +/// `enqueueWorkItem:`. +/// +/// MTRAsyncWorkQueue is thread-safe. MTR_TESTABLE -@interface MTRAsyncWorkItem : NSObject +@interface MTRAsyncWorkQueue : NSObject + - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; -// Both readyHandler and cancelHander will be called on the queue given to initWithQueue -- (instancetype)initWithQueue:(dispatch_queue_t)queue; -@property (nonatomic, strong) MTRAsyncWorkReadyHandler readyHandler; -@property (nonatomic, strong) dispatch_block_t cancelHandler; - -// Called by the creater of the work item when async work is done and should -// be removed from the queue. The work queue will run the next work item. -// Note: This must only be called from within the readyHandler -- (void)endWork; - -// Called by the creater of the work item when async work should be retried. -// The work queue will call this workItem's readyHandler again. -// Note: This must only be called from within the readyHandler -- (void)retryWork; +/// Creates a work queue with the given context object. +/// +/// The context object is weakly held and passed to the readyHandler of work +/// items. This avoids work item blocks accidentally creating a retain cycle +/// by strongly closing over the context object themselves (since the context +/// object will generally be holding a strong reference to the work queue +/// itself). The owner of the queue is responsible for keeping the context +/// object alive; no further work items will be executed if the context object +/// is lost. +- (instancetype)initWithContext:(ContextType)context; + +/// Enqueues the specified work item, making it eligible for execution. +/// +/// Once a work item is enqueued, ownership of it passes to the queue and +/// no further modifications may be made to it. Work item objects cannot be +/// re-used. +- (void)enqueueWorkItem:(MTRAsyncWorkItem *)item; + +/// Checks whether the queue already contains a work item matching the provided +/// details. A client may call this method to avoid enqueueing duplicate work. +/// +/// This method will call the duplicate check handler for all work items +/// matching the duplicate type ID, starting from the last item in the queue +/// +/// @see MTRAsyncWorkDuplicateCheckHandler +- (BOOL)hasDuplicateForTypeID:(NSUInteger)opaqueDuplicateTypeID + workItemData:(id)opaqueWorkItemData; + +/// Cancels and removes all work items. +- (void)invalidate; @end NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRAsyncWorkQueue.mm b/src/darwin/Framework/CHIP/MTRAsyncWorkQueue.mm index 98291126a31728..4de523ec0cd889 100644 --- a/src/darwin/Framework/CHIP/MTRAsyncWorkQueue.mm +++ b/src/darwin/Framework/CHIP/MTRAsyncWorkQueue.mm @@ -15,325 +15,303 @@ * limitations under the License. */ -#import -#import - -#import "MTRAsyncWorkQueue_Internal.h" +#import "MTRAsyncWorkQueue.h" +#import "MTRDefines_Internal.h" #import "MTRLogging_Internal.h" -#pragma mark - Class extensions - -@interface MTRAsyncWorkQueue () -// The lock protects the internal state of the work queue so that these may be called from any queue or thread: -// -enqueueWorkItem: -// -invalidate -// -endWork: -// -retryWork: -@property (nonatomic, readonly) os_unfair_lock lock; -@property (nonatomic, strong, readonly) id context; -@property (nonatomic, strong, readonly) dispatch_queue_t queue; -@property (nonatomic, strong, readonly) NSMutableArray * items; -@property (nonatomic, readwrite) NSUInteger runningWorkItemCount; - -// For WorkItem's use only - the parameter is for sanity check -- (void)endWork:(MTRAsyncWorkItem *)workItem; -- (void)retryWork:(MTRAsyncWorkItem *)workItem; -@end +#import -@interface MTRAsyncWorkItem () -@property (nonatomic, readonly) os_unfair_lock lock; -@property (nonatomic, strong, readonly) dispatch_queue_t queue; -@property (nonatomic, readwrite) NSUInteger retryCount; -@property (nonatomic, strong) MTRAsyncWorkQueue * workQueue; -@property (nonatomic, readonly) BOOL enqueued; -// Called by the queue -- (void)markedEnqueued; -- (void)callReadyHandlerWithContext:(id)context; -- (void)cancel; -@end +typedef NS_ENUM(NSInteger, MTRAsyncWorkItemState) { + MTRAsyncWorkItemMutable, + MTRAsyncWorkItemComplete, + MTRAsyncWorkItemEnqueued, + MTRAsyncWorkItemRunning, + MTRAsyncWorkItemRetryCountBase = MTRAsyncWorkItemRunning, // values >= MTRAsyncWorkItemRunning encode retryCount +}; + +MTR_DIRECT_MEMBERS +@implementation MTRAsyncWorkItem { + dispatch_queue_t _queue; + MTRAsyncWorkItemState _state; // protected by queue lock once enqueued +} -#pragma mark - Class implementations +#pragma mark Configuration by the client -@implementation MTRAsyncWorkQueue -- (instancetype)initWithContext:(id)context queue:(dispatch_queue_t)queue +- (instancetype)initWithQueue:(dispatch_queue_t)queue { + NSParameterAssert(queue); if (self = [super init]) { - _lock = OS_UNFAIR_LOCK_INIT; - _context = context; _queue = queue; - _items = [NSMutableArray array]; - MTR_LOG_INFO("MTRAsyncCallbackWorkQueue init for context %@", context); + _state = MTRAsyncWorkItemMutable; } return self; } -- (NSString *)description +- (void)setReadyHandler:(void (^)(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion))readyHandler { - os_unfair_lock_lock(&_lock); - - auto * desc = [NSString - stringWithFormat:@"MTRAsyncCallbackWorkQueue context: %@ items count: %lu", self.context, (unsigned long) self.items.count]; - - os_unfair_lock_unlock(&_lock); - - return desc; + [self assertMutable]; + _readyHandler = readyHandler; } -- (void)enqueueWorkItem:(MTRAsyncWorkItem *)item +- (void)setCancelHandler:(void (^)(void))cancelHandler { - if (item.enqueued) { - MTR_LOG_ERROR("MTRAsyncCallbackWorkQueue enqueueWorkItem: item cannot be enqueued twice"); - return; - } - - [item markedEnqueued]; - - os_unfair_lock_lock(&_lock); - item.workQueue = self; - [self.items addObject:item]; - - [self _callNextReadyWorkItem]; - os_unfair_lock_unlock(&_lock); + [self assertMutable]; + _cancelHandler = cancelHandler; } -- (void)invalidate +- (void)setBatchingID:(NSUInteger)opaqueBatchingID data:(id)opaqueBatchableData handler:(MTRAsyncWorkBatchingHandler)batchingHandler { - os_unfair_lock_lock(&_lock); - NSMutableArray * invalidateItems = _items; - _items = nil; - os_unfair_lock_unlock(&_lock); - - MTR_LOG_INFO( - "MTRAsyncCallbackWorkQueue invalidate for context %@ items count: %lu", _context, (unsigned long) invalidateItems.count); - for (MTRAsyncWorkItem * item in invalidateItems) { - [item cancel]; - } - [invalidateItems removeAllObjects]; + NSParameterAssert(batchingHandler); + [self assertMutable]; + _batchingID = opaqueBatchingID; + _batchableData = opaqueBatchableData; + _batchingHandler = batchingHandler; } -// called after executing a work item -- (void)_postProcessWorkItem:(MTRAsyncWorkItem *)workItem retry:(BOOL)retry +- (void)setDuplicateTypeID:(NSUInteger)opaqueDuplicateTypeID handler:(MTRAsyncWorkDuplicateCheckHandler)duplicateCheckHandler { - os_unfair_lock_lock(&_lock); - // sanity check if running - if (!self.runningWorkItemCount) { - // something is wrong with state - nothing is currently running - os_unfair_lock_unlock(&_lock); - MTR_LOG_ERROR("MTRAsyncCallbackWorkQueue endWork: no work is running on work queue"); - return; - } - - // sanity check the same work item is running - // when "concurrency width" is implemented need to check first N items - MTRAsyncWorkItem * firstWorkItem = self.items.firstObject; - if (firstWorkItem != workItem) { - // something is wrong with this work item - should not be currently running - os_unfair_lock_unlock(&_lock); - MTR_LOG_ERROR("MTRAsyncCallbackWorkQueue endWork: work item is not first on work queue"); - return; - } - - // if work item is done (no need to retry), remove from queue and call ready on the next item - if (!retry) { - [self.items removeObjectAtIndex:0]; - } + NSParameterAssert(duplicateCheckHandler); + [self assertMutable]; + _duplicateTypeID = opaqueDuplicateTypeID; + _duplicateCheckHandler = duplicateCheckHandler; +} - // when "concurrency width" is implemented this will be decremented instead - self.runningWorkItemCount = 0; - [self _callNextReadyWorkItem]; - os_unfair_lock_unlock(&_lock); +- (void)assertMutable +{ + NSAssert(_state == MTRAsyncWorkItemMutable, @"work item is not mutable (%ld)", (long) _state); } -- (void)endWork:(MTRAsyncWorkItem *)workItem +#pragma mark Management by the work queue (queue lock held) + +- (void)markEnqueued { - [self _postProcessWorkItem:workItem retry:NO]; + [self assertMutable]; + _state = MTRAsyncWorkItemEnqueued; } -- (void)retryWork:(MTRAsyncWorkItem *)workItem +- (NSInteger)retryCount { - [self _postProcessWorkItem:workItem retry:YES]; + switch (_state) { + case MTRAsyncWorkItemMutable: + case MTRAsyncWorkItemComplete: + case MTRAsyncWorkItemEnqueued: + return 0; + default: + return ((NSInteger) _state) - MTRAsyncWorkItemRetryCountBase; + } } -// assume lock is held while calling this -- (void)_callNextReadyWorkItem +- (void)callReadyHandlerWithContext:(id)context completion:(MTRAsyncWorkCompletionBlock)completion { - // when "concurrency width" is implemented this will be checked against the width - if (self.runningWorkItemCount) { - // can't run next work item until the current one is done - return; + // + NSAssert(_state >= MTRAsyncWorkItemEnqueued, @"work item is not enqueued (%ld)", (long) _state); + NSInteger retryCount = 0; + if (_state == MTRAsyncWorkItemEnqueued) { + _state = MTRAsyncWorkItemRunning; + } else if (_state >= MTRAsyncWorkItemRunning) { + retryCount = (_state - MTRAsyncWorkItemRetryCountBase) + 1; // increment retryCount + _state = (MTRAsyncWorkItemState) (MTRAsyncWorkItemRetryCountBase + retryCount); + } else { + return; // asserted above } - // only proceed to mark queue as running if there are items to run - if (self.items.count) { - // when "concurrency width" is implemented this will be incremented instead - self.runningWorkItemCount = 1; - - MTRAsyncWorkItem * workItem = self.items.firstObject; - - // Check if batching is possible or needed. Only ask work item to batch once for simplicity - if (workItem.batchable && workItem.batchingHandler && (workItem.retryCount == 0)) { - while (self.items.count >= 2) { - MTRAsyncWorkItem * nextWorkItem = self.items[1]; - if (!nextWorkItem.batchable || (nextWorkItem.batchingID != workItem.batchingID)) { - // next item is not eligible to merge with this one - break; - } - - BOOL fullyMerged = NO; - workItem.batchingHandler(workItem.batchableData, nextWorkItem.batchableData, &fullyMerged); - if (!fullyMerged) { - // We can't remove the next work item, so we can't merge anything else into this one. - break; - } - - [self.items removeObjectAtIndex:1]; - } + // Always dispatch even if there is no readyHandler as this avoids synchronously + // re-entering the MTRAsyncWorkQueueCode, simplifying the implementation. + auto readyHandler = _readyHandler; + dispatch_async(_queue, ^{ + if (readyHandler) { + readyHandler(context, retryCount, completion); + } else { + completion(MTRAsyncWorkComplete); } - - [workItem callReadyHandlerWithContext:self.context]; - } + }); } -- (BOOL)isDuplicateForTypeID:(NSUInteger)opaqueDuplicateTypeID workItemData:(id)opaqueWorkItemData +- (void)cancel { - os_unfair_lock_lock(&_lock); - // Start from the last item - for (NSUInteger i = self.items.count; i > 0; i--) { - MTRAsyncWorkItem * item = self.items[i - 1]; - BOOL isDuplicate = NO; - BOOL stop = NO; - if (item.supportsDuplicateCheck && (item.duplicateTypeID == opaqueDuplicateTypeID) && item.duplicateCheckHandler) { - item.duplicateCheckHandler(opaqueWorkItemData, &isDuplicate, &stop); - if (stop) { - os_unfair_lock_unlock(&_lock); - return isDuplicate; - } + if (_state != MTRAsyncWorkItemComplete) { + auto cancelHandler = _cancelHandler; + [self markComplete]; + if (cancelHandler) { + // Note that if the work item was running it may call the work + // completion handler before the cancel handler actually runs, + // however in this case the work completion handler will return + // NO, giving the work code the ability to deal with this race if + // necessary. + dispatch_async(_queue, cancelHandler); } } - os_unfair_lock_unlock(&_lock); - return NO; } -@end -@implementation MTRAsyncWorkItem - -- (instancetype)initWithQueue:(dispatch_queue_t)queue +- (BOOL)isComplete { - if (self = [super init]) { - _lock = OS_UNFAIR_LOCK_INIT; - _queue = queue; - } - return self; + return _state == MTRAsyncWorkItemComplete; } -// assume lock is held -- (void)_invalidate +- (void)markComplete { - // Make sure we don't leak via handlers that close over us, as ours must. - // This is a bit odd, since these are supposed to be non-nullable - // properties, but it's the best we can do given our API surface, unless we - // assume that all consumers consistently use __weak refs to us inside their - // handlers. - // - // Setting the attributes to nil will not compile; set the ivars directly. + NSAssert(_state >= MTRAsyncWorkItemEnqueued, @"work item was not enqueued (%ld)", (long) _state); + _state = MTRAsyncWorkItemComplete; + + // Clear all handlers in case any of them captured this object. _readyHandler = nil; _cancelHandler = nil; + _batchingHandler = nil; + _duplicateCheckHandler = nil; } -- (void)invalidate +@end + +MTR_DIRECT_MEMBERS +@implementation MTRAsyncWorkQueue { + os_unfair_lock _lock; + __weak id _context; + NSMutableArray * _items; + NSInteger _runningWorkItemCount; +} + +- (instancetype)initWithContext:(id)context { - os_unfair_lock_lock(&_lock); - [self _invalidate]; - os_unfair_lock_unlock(&_lock); + NSParameterAssert(context); + if (self = [super init]) { + _context = context; + _items = [NSMutableArray array]; + } + return self; } -- (void)markedEnqueued +- (NSString *)description { os_unfair_lock_lock(&_lock); - _enqueued = YES; + auto * result = [NSString stringWithFormat:@"<%@ context: %@ items count: %tu>", self.class, _context, _items.count]; os_unfair_lock_unlock(&_lock); + return result; } -- (void)setReadyHandler:(MTRAsyncWorkReadyHandler)readyHandler +- (void)enqueueWorkItem:(MTRAsyncWorkItem *)item { + NSParameterAssert(item); + NSAssert(_context, @"context has been lost"); + os_unfair_lock_lock(&_lock); - if (!_enqueued) { - _readyHandler = readyHandler; - } + [item markEnqueued]; + [_items addObject:item]; + [self _callNextReadyWorkItem]; os_unfair_lock_unlock(&_lock); } -- (void)setCancelHandler:(dispatch_block_t)cancelHandler +- (void)invalidate { + NSString * contextDescription = [_context description]; // outside of lock os_unfair_lock_lock(&_lock); - if (!_enqueued) { - _cancelHandler = cancelHandler; + MTR_LOG_INFO("MTRAsyncWorkQueue<%@> invalidate %tu items", contextDescription, _items.count); + for (MTRAsyncWorkItem * item in _items) { + [item cancel]; } + [_items removeAllObjects]; os_unfair_lock_unlock(&_lock); } -- (void)endWork +- (void)_postProcessWorkItem:(MTRAsyncWorkItem *)workItem retry:(BOOL)retry { - [self.workQueue endWork:self]; - [self invalidate]; -} + os_unfair_lock_assert_owner(&_lock); -- (void)retryWork -{ - [self.workQueue retryWork:self]; -} + MTRAsyncWorkItem * runningWorkItem = (_runningWorkItemCount) ? _items.firstObject : nil; + if (workItem != runningWorkItem) { + NSAssert(NO, @"work item to post-process is not running"); + return; + } -// Called by the work queue -- (void)callReadyHandlerWithContext:(id)context -{ - dispatch_async(self.queue, ^{ - os_unfair_lock_lock(&self->_lock); - MTRAsyncWorkReadyHandler readyHandler = self->_readyHandler; - NSUInteger retryCount = self->_retryCount; - if (readyHandler) { - self->_retryCount++; - } - os_unfair_lock_unlock(&self->_lock); + // if work item is done (no need to retry), remove from queue and call ready on the next item + if (!retry) { + [workItem markComplete]; + [_items removeObjectAtIndex:0]; + } - if (readyHandler == nil) { - // Nothing to do here. - [self endWork]; - } else { - readyHandler(context, retryCount); - } - }); + // when "concurrency width" is implemented this will be decremented instead + _runningWorkItemCount = 0; + [self _callNextReadyWorkItem]; } -// Called by the work queue -- (void)cancel +- (void)_callNextReadyWorkItem { - os_unfair_lock_lock(&self->_lock); - dispatch_block_t cancelHandler = self->_cancelHandler; - [self _invalidate]; - os_unfair_lock_unlock(&self->_lock); - - if (cancelHandler) { - dispatch_async(self.queue, ^{ - cancelHandler(); - }); + os_unfair_lock_assert_owner(&_lock); + + // when "concurrency width" is implemented this will be checked against the width + if (_runningWorkItemCount) { + return; // can't run next work item until the current one is done } -} -- (void)setBatchingID:(NSUInteger)opaqueBatchingID data:(id)opaqueBatchableData handler:(MTRAsyncWorkBatchingHandler)batchingHandler -{ - os_unfair_lock_lock(&self->_lock); - _batchable = YES; - _batchingID = opaqueBatchingID; - _batchableData = opaqueBatchableData; - _batchingHandler = batchingHandler; - os_unfair_lock_unlock(&self->_lock); + if (!_items.count) { + return; // nothing to run + } + + id context = _context; + if (!context) { + MTR_LOG_ERROR("MTRAsyncWorkQueue context has been lost, dropping queued work items"); + [_items removeAllObjects]; + return; + } + + // when "concurrency width" is implemented this will be incremented instead + _runningWorkItemCount = 1; + + MTRAsyncWorkItem * workItem = _items.firstObject; + + // Check if batching is possible or needed. Only ask work item to batch once for simplicity + auto batchingHandler = workItem.batchingHandler; + if (batchingHandler && workItem.retryCount == 0) { + while (_items.count >= 2) { + MTRAsyncWorkItem * nextWorkItem = _items[1]; + if (!nextWorkItem.batchingHandler || nextWorkItem.batchingID != workItem.batchingID) { + break; // next item is not eligible to merge with this one + } + + BOOL fullyMerged = NO; + batchingHandler(workItem.batchableData, nextWorkItem.batchableData, &fullyMerged); + if (!fullyMerged) { + break; // not removing the next item, so we can't merge anything else + } + + [_items removeObjectAtIndex:1]; + } + } + + mtr_weakify(self); + [workItem callReadyHandlerWithContext:context completion:^(MTRAsyncWorkOutcome outcome) { + mtr_strongify(self); + BOOL handled = NO; + if (self) { + os_unfair_lock_lock(&self->_lock); + if (!workItem.isComplete) { + [self _postProcessWorkItem:workItem retry:(outcome == MTRAsyncWorkNeedsRetry)]; + handled = YES; + } + os_unfair_lock_unlock(&self->_lock); + } + return handled; + }]; } -- (void)setDuplicateTypeID:(NSUInteger)opaqueDuplicateTypeID handler:(MTRAsyncWorkDuplicateCheckHandler)duplicateCheckHandler +- (BOOL)hasDuplicateForTypeID:(NSUInteger)opaqueDuplicateTypeID workItemData:(id)opaqueWorkItemData { - _supportsDuplicateCheck = YES; - _duplicateTypeID = opaqueDuplicateTypeID; - _duplicateCheckHandler = duplicateCheckHandler; + BOOL hasDuplicate = NO; + os_unfair_lock_lock(&_lock); + // Start from the last item + for (MTRAsyncWorkItem * item in [_items reverseObjectEnumerator]) { + auto duplicateCheckHandler = item.duplicateCheckHandler; + if (duplicateCheckHandler && item.duplicateTypeID == opaqueDuplicateTypeID) { + BOOL stop = NO; + BOOL isDuplicate = NO; + duplicateCheckHandler(opaqueWorkItemData, &isDuplicate, &stop); + if (stop) { + hasDuplicate = isDuplicate; + break; + } + } + } + os_unfair_lock_unlock(&_lock); + return hasDuplicate; } @end diff --git a/src/darwin/Framework/CHIP/MTRAsyncWorkQueue_Internal.h b/src/darwin/Framework/CHIP/MTRAsyncWorkQueue_Internal.h deleted file mode 100644 index 54995effd8a8c7..00000000000000 --- a/src/darwin/Framework/CHIP/MTRAsyncWorkQueue_Internal.h +++ /dev/null @@ -1,102 +0,0 @@ -/** - * - * Copyright (c) 2022 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import - -#import "MTRAsyncWorkQueue.h" - -NS_ASSUME_NONNULL_BEGIN - -@class MTRDevice; - -// Optional feature: Work Item Batching -// When a work item is dequeued to run, if it is of a type that can be combined with similar work items in a batch, this facility -// gives the client of this API an opportunity to coalesce and merge work items. -// - The "batching ID" is used for grouping mergeable work items with unique merging strategies. The ID value is opaque to this -// API, and the API client is responsible for assigning them. -// - Each work item will only be asked to batch before it's first dequeued to run readyHandler. -// See the MTRAsyncWorkBatchingHandler definition for more details. - -// The batching handler is called by the work queue when all of the following are true: -// -// 1) A work item that is batchable is about to be dequeued and executed for the first time. -// 2) The next work item in the queue is also batchable. -// 3) The two work items have matching batching ids. -// -// The handler will be passed the opaque data of the two work items: opaqueDataCurrent is the data of the -// item about to be executed and opaqueDataNext is the data for the next item. -// -// The handler is expected to mutate the data as needed to achieve batching. -// -// If after the data mutations opaqueDataNext no longer requires any work, the handler should set *fullyMerged to YES to indicate -// that the next item can be dropped from the queue. Otherwise the handler should set *fullyMerged to NO. -// -// If *fullyMerged is set to YES, this handler may be called again to possibly also batch the work item -// after the one that was dropped. -typedef void (^MTRAsyncWorkBatchingHandler)(id opaqueDataCurrent, id opaqueDataNext, BOOL * fullyMerged); - -// Optional feature: Duplicate Filtering -// This is a facility that enables the API client to check if a potential work item has already been enqueued. By providing a -// handler that can answer if a work item's relevant data is a duplicate, it can avoid redundant queuing of requests. -// - The "duplicate type ID" is used for grouping different types of work items for duplicate checking. The ID value is opaque -// to this API, and the API client is responsible for assigning them. -// See the MTRAsyncWorkDuplicateCheckHandler definition and the WorkQueue's -isDuplicateForTypeID:workItemData: method -// descriptions for more details. - -// The duplicate check handler is called by the work queue when the client wishes to check whether a work item is a duplicate of an -// existing one, so that the client may decide to not enqueue a duplicate work item. -// -// The handler will be passed the opaque data of a potential duplicate work item. -// -// If the handler determines the data is indeed duplicate work, it should set *stop to YES, and set *isDuplicate to YES. -// -// If the handler determines the data is not duplicate work, it should set *stop to YES, and set *isDuplicate to NO. -// -// If the handler is unable to determine if the data is duplicate work, it should set *stop to NO. -// In this case, the value of *isDuplicate is not examined. -typedef void (^MTRAsyncWorkDuplicateCheckHandler)(id opaqueItemData, BOOL * isDuplicate, BOOL * stop); - -@interface MTRAsyncWorkQueue () -// The MTRDevice object is only held and passed back as a reference and is opaque to the queue -- (instancetype)initWithContext:(id _Nullable)context queue:(dispatch_queue_t)queue; - -// Before creating a work item, a client may call this method to check with existing work items that the new potential work item -// data is not a duplicate request. -// - This method will call the duplicate check handler for all work items matching the duplicate type ID, starting from the last -// item in the queue, and if a handler sets *stop to YES, this method will return the value the handler sets for *isDuplicate -// - If no duplicate check handlers set *stop to YES, this method will return NO. -- (BOOL)isDuplicateForTypeID:(NSUInteger)opaqueDuplicateTypeID workItemData:(id)opaqueWorkItemData; -@end - -@interface MTRAsyncWorkItem () -// Batching -@property (nonatomic, readonly) BOOL batchable; -@property (nonatomic, readonly) NSUInteger batchingID; -@property (nonatomic, readonly) id batchableData; -@property (nonatomic, readonly) MTRAsyncWorkBatchingHandler batchingHandler; -- (void)setBatchingID:(NSUInteger)opaqueBatchingID - data:(id)opaqueBatchableData - handler:(MTRAsyncWorkBatchingHandler)batchingHandler; - -// Duplicate check -@property (nonatomic, readonly) BOOL supportsDuplicateCheck; -@property (nonatomic, readonly) NSUInteger duplicateTypeID; -@property (nonatomic, readonly) MTRAsyncWorkDuplicateCheckHandler duplicateCheckHandler; -- (void)setDuplicateTypeID:(NSUInteger)opaqueDuplicateTypeID handler:(MTRAsyncWorkDuplicateCheckHandler)duplicateCheckHandler; -@end - -NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDefines_Internal.h b/src/darwin/Framework/CHIP/MTRDefines_Internal.h index 674d52f60fdb2c..d5d7040a927681 100644 --- a/src/darwin/Framework/CHIP/MTRDefines_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDefines_Internal.h @@ -33,3 +33,17 @@ #else #define MTR_TESTABLE MTR_HIDDEN #endif + +// clang-format off +/// Creates a weak shadow copy of the variable `local` +#define mtr_weakify(local) \ + __weak typeof(local) _mtr_weak_##local = local + +/// Copies the weak shadow copy of `local` created by `mtr_weakify` +/// back into a strong variable of the same name. +#define mtr_strongify(local) \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wshadow\"") \ + __strong typeof(local) _Nullable local = _mtr_weak_##local \ + _Pragma("clang diagnostic pop") +// clang-format on diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index ea5d9e800de8e5..2ed4a67c4e6bd7 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -18,7 +18,7 @@ #import #import -#import "MTRAsyncWorkQueue_Internal.h" +#import "MTRAsyncWorkQueue.h" #import "MTRAttributeSpecifiedCheck.h" #import "MTRBaseDevice_Internal.h" #import "MTRBaseSubscriptionCallback.h" @@ -207,7 +207,7 @@ - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControlle = dispatch_queue_create("org.csa-iot.matter.framework.device.workqueue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); _readCache = [NSMutableDictionary dictionary]; _expectedValueCache = [NSMutableDictionary dictionary]; - _asyncCallbackWorkQueue = [[MTRAsyncWorkQueue alloc] initWithContext:self queue:_queue]; + _asyncWorkQueue = [[MTRAsyncWorkQueue alloc] initWithContext:self]; _state = MTRDeviceStateUnknown; MTR_LOG_INFO("%@ init with hex nodeID 0x%016llX", self, _nodeID.unsignedLongLongValue); } @@ -246,6 +246,9 @@ - (void)setDelegate:(id)delegate queue:(dispatch_queue_t)queu - (void)invalidate { MTR_LOG_INFO("%@ invalidate", self); + + [_asyncWorkQueue invalidate]; + os_unfair_lock_lock(&self->_lock); _weakDelegate = nil; @@ -381,7 +384,7 @@ - (void)_handleSubscriptionReset } MTR_LOG_DEFAULT("%@ scheduling to reattempt subscription in %u seconds", self, _lastSubscriptionAttemptWait); - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_lastSubscriptionAttemptWait * NSEC_PER_SEC)), self.queue, ^{ + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (_lastSubscriptionAttemptWait * NSEC_PER_SEC)), self.queue, ^{ os_unfair_lock_lock(&self->_lock); [self _reattemptSubscriptionNowIfNeeded]; os_unfair_lock_unlock(&self->_lock); @@ -882,7 +885,7 @@ static BOOL AttributeHasChangesOmittedQuality(MTRAttributePath * attributePath) NSArray * readRequestData = @[ readRequestPath, params ?: [NSNull null] ]; // But first, check if a duplicate read request is already queued and return - if ([_asyncCallbackWorkQueue isDuplicateForTypeID:MTRDeviceWorkItemDuplicateReadTypeID workItemData:readRequestData]) { + if ([_asyncWorkQueue hasDuplicateForTypeID:MTRDeviceWorkItemDuplicateReadTypeID workItemData:readRequestData]) { return attributeValueToReturn; } @@ -890,12 +893,10 @@ static BOOL AttributeHasChangesOmittedQuality(MTRAttributePath * attributePath) // Create work item, set ready handler to perform task, then enqueue the work MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.queue]; - MTRAsyncWorkBatchingHandler batchingHandler = ^(id opaqueDataCurrent, id opaqueDataNext, BOOL * fullyMerged) { + [workItem setBatchingID:MTRDeviceWorkItemBatchingReadID data:readRequests handler:^(id opaqueDataCurrent, id opaqueDataNext, BOOL * fullyMerged) { NSMutableArray * readRequestsCurrent = opaqueDataCurrent; NSMutableArray * readRequestsNext = opaqueDataNext; - *fullyMerged = NO; - // Can only read up to 9 paths at a time, per spec if (readRequestsCurrent.count >= 9) { MTR_LOG_DEFAULT("%@ batching cannot add more", logPrefix); @@ -927,8 +928,8 @@ static BOOL AttributeHasChangesOmittedQuality(MTRAttributePath * attributePath) MTR_LOG_DEFAULT("%@ batching - fully merged next item", logPrefix); *fullyMerged = YES; } - }; - MTRAsyncWorkDuplicateCheckHandler duplicateCheckHandler = ^(id opaqueItemData, BOOL * isDuplicate, BOOL * stop) { + }]; + [workItem setDuplicateTypeID:MTRDeviceWorkItemDuplicateReadTypeID handler:^(id opaqueItemData, BOOL * isDuplicate, BOOL * stop) { for (NSArray * readItem in readRequests) { if ([readItem isEqual:opaqueItemData]) { MTR_LOG_DEFAULT("%@ duplicate check found %@ - report duplicate", logPrefix, readItem); @@ -938,14 +939,14 @@ static BOOL AttributeHasChangesOmittedQuality(MTRAttributePath * attributePath) } } *stop = NO; - }; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTR_LOG_DEFAULT("%@ dequeueWorkItem %@", logPrefix, self->_asyncCallbackWorkQueue); + }]; + [workItem setReadyHandler:^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { + MTR_LOG_DEFAULT("%@ dequeueWorkItem %@", logPrefix, self->_asyncWorkQueue); // Sanity check if (readRequests.count == 0) { MTR_LOG_ERROR("%@ dequeueWorkItem no read requests", logPrefix); - [workItem endWork]; + completion(MTRAsyncWorkComplete); return; } @@ -955,7 +956,7 @@ static BOOL AttributeHasChangesOmittedQuality(MTRAttributePath * attributePath) // Sanity check if (readItem.count < 2) { MTR_LOG_ERROR("%@ dequeueWorkItem read item missing info %@", logPrefix, readItem); - [workItem endWork]; + completion(MTRAsyncWorkComplete); return; } [attributePaths addObject:readItem[MTRDeviceReadRequestFieldPathIndex]]; @@ -981,18 +982,15 @@ static BOOL AttributeHasChangesOmittedQuality(MTRAttributePath * attributePath) // TODO: better retry logic if (error && (retryCount < 2)) { MTR_LOG_ERROR("%@ completion error %@ retryWork %lu", logPrefix, error, (unsigned long) retryCount); - [workItem retryWork]; + completion(MTRAsyncWorkNeedsRetry); } else { MTR_LOG_DEFAULT("%@ completion error %@ endWork", logPrefix, error); - [workItem endWork]; + completion(MTRAsyncWorkComplete); } }]; - }; - workItem.readyHandler = readyHandler; - [workItem setBatchingID:MTRDeviceWorkItemBatchingReadID data:readRequests handler:batchingHandler]; - [workItem setDuplicateTypeID:MTRDeviceWorkItemDuplicateReadTypeID handler:duplicateCheckHandler]; - MTR_LOG_DEFAULT("%@ enqueueWorkItem %@", logPrefix, _asyncCallbackWorkQueue); - [_asyncCallbackWorkQueue enqueueWorkItem:workItem]; + }]; + MTR_LOG_DEFAULT("%@ enqueueWorkItem %@", logPrefix, _asyncWorkQueue); + [_asyncWorkQueue enqueueWorkItem:workItem]; } return attributeValueToReturn; @@ -1023,12 +1021,12 @@ - (void)writeAttributeWithEndpointID:(NSNumber *)endpointID MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.queue]; // The write operation will install a duplicate check handler, to return NO for "isDuplicate". Since a write operation may // change values, only read requests after this should be considered for duplicate requests. - MTRAsyncWorkDuplicateCheckHandler duplicateCheckHandler = ^(id opaqueItemData, BOOL * isDuplicate, BOOL * stop) { + [workItem setDuplicateTypeID:MTRDeviceWorkItemDuplicateReadTypeID handler:^(id opaqueItemData, BOOL * isDuplicate, BOOL * stop) { *isDuplicate = NO; *stop = YES; - }; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTR_LOG_DEFAULT("%@ dequeueWorkItem %@", logPrefix, self->_asyncCallbackWorkQueue); + }]; + [workItem setReadyHandler:^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { + MTR_LOG_DEFAULT("%@ dequeueWorkItem %@", logPrefix, self->_asyncWorkQueue); MTRBaseDevice * baseDevice = [self newBaseDevice]; [baseDevice writeAttributeWithEndpointID:endpointID @@ -1039,16 +1037,14 @@ - (void)writeAttributeWithEndpointID:(NSNumber *)endpointID queue:self.queue completion:^(NSArray *> * _Nullable values, NSError * _Nullable error) { MTR_LOG_DEFAULT("%@ completion error %@ endWork", logPrefix, error); - [workItem endWork]; if (error) { [self removeExpectedValueForAttributePath:attributePath expectedValueID:expectedValueID]; } + completion(MTRAsyncWorkComplete); }]; - }; - workItem.readyHandler = readyHandler; - [workItem setDuplicateTypeID:MTRDeviceWorkItemDuplicateReadTypeID handler:duplicateCheckHandler]; - MTR_LOG_DEFAULT("%@ enqueueWorkItem %@", logPrefix, _asyncCallbackWorkQueue); - [_asyncCallbackWorkQueue enqueueWorkItem:workItem]; + }]; + MTR_LOG_DEFAULT("%@ enqueueWorkItem %@", logPrefix, _asyncWorkQueue); + [_asyncWorkQueue enqueueWorkItem:workItem]; } - (void)invokeCommandWithEndpointID:(NSNumber *)endpointID @@ -1083,12 +1079,12 @@ - (void)invokeCommandWithEndpointID:(NSNumber *)endpointID MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.queue]; // The command operation will install a duplicate check handler, to return NO for "isDuplicate". Since a command operation may // change values, only read requests after this should be considered for duplicate requests. - MTRAsyncWorkDuplicateCheckHandler duplicateCheckHandler = ^(id opaqueItemData, BOOL * isDuplicate, BOOL * stop) { + [workItem setDuplicateTypeID:MTRDeviceWorkItemDuplicateReadTypeID handler:^(id opaqueItemData, BOOL * isDuplicate, BOOL * stop) { *isDuplicate = NO; *stop = YES; - }; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTR_LOG_DEFAULT("%@ dequeueWorkItem %@", logPrefix, self->_asyncCallbackWorkQueue); + }]; + [workItem setReadyHandler:^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTR_LOG_DEFAULT("%@ dequeueWorkItem %@", logPrefix, self->_asyncWorkQueue); MTRBaseDevice * baseDevice = [self newBaseDevice]; [baseDevice invokeCommandWithEndpointID:endpointID @@ -1101,20 +1097,18 @@ - (void)invokeCommandWithEndpointID:(NSNumber *)endpointID // Log the data at the INFO level (not usually persisted permanently), // but make sure we log the work completion at the DEFAULT level. MTR_LOG_INFO("%@ received response: %@ error: %@", logPrefix, values, error); - MTR_LOG_DEFAULT("%@ endWork", logPrefix); dispatch_async(queue, ^{ completion(values, error); }); - [workItem endWork]; if (error && expectedValues) { [self removeExpectedValuesForAttributePaths:attributePaths expectedValueID:expectedValueID]; } + MTR_LOG_DEFAULT("%@ endWork", logPrefix); + workCompletion(MTRAsyncWorkComplete); }]; - }; - workItem.readyHandler = readyHandler; - [workItem setDuplicateTypeID:MTRDeviceWorkItemDuplicateReadTypeID handler:duplicateCheckHandler]; - MTR_LOG_DEFAULT("%@ enqueueWorkItem %@", logPrefix, _asyncCallbackWorkQueue); - [_asyncCallbackWorkQueue enqueueWorkItem:workItem]; + }]; + MTR_LOG_DEFAULT("%@ enqueueWorkItem %@", logPrefix, _asyncWorkQueue); + [_asyncWorkQueue enqueueWorkItem:workItem]; } - (void)openCommissioningWindowWithSetupPasscode:(NSNumber *)setupPasscode @@ -1198,7 +1192,7 @@ - (void)_checkExpiredExpectedValues waitTime = MTR_DEVICE_EXPIRATION_CHECK_TIMER_MINIMUM_WAIT_TIME; } MTRWeakReference * weakSelf = [MTRWeakReference weakReferenceWithObject:self]; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(waitTime * NSEC_PER_SEC)), self.queue, ^{ + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (waitTime * NSEC_PER_SEC)), self.queue, ^{ MTRDevice * strongSelf = weakSelf.strongObject; [strongSelf _performScheduledExpirationCheck]; }); diff --git a/src/darwin/Framework/CHIP/MTRDevice_Internal.h b/src/darwin/Framework/CHIP/MTRDevice_Internal.h index 7815fe2e5d44c2..cd94bfbb673d52 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDevice_Internal.h @@ -19,6 +19,8 @@ #import #import +#import "MTRAsyncWorkQueue.h" + #include NS_ASSUME_NONNULL_BEGIN @@ -44,11 +46,9 @@ typedef void (^MTRDevicePerformAsyncBlock)(MTRBaseDevice * baseDevice); @property (nonatomic, readonly) MTRDeviceController * deviceController; @property (nonatomic, readonly, copy) NSNumber * nodeID; -// Queue used for various internal bookkeeping work. In general endWork calls -// on work items should happen on this queue, so we don't block progress of the -// asyncCallbackWorkQueue on any client code. +// Queue used for various internal bookkeeping work. @property (nonatomic) dispatch_queue_t queue; -@property (nonatomic, readonly) MTRAsyncWorkQueue * asyncCallbackWorkQueue; +@property (nonatomic, readonly) MTRAsyncWorkQueue * asyncWorkQueue; @end diff --git a/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt b/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt index a4afcd5c8bace0..d33c75124c462a 100644 --- a/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt @@ -114,8 +114,8 @@ completionHandler // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[{{> baseCluster}} alloc] initWithDevice:baseDevice endpointID:@(self.endpoint) queue:self.device.queue]; [cluster {{asLowerCamelCase name}}WithParams:params {{> completionName}}: @@ -127,7 +127,7 @@ completionHandler not great from a type-safety perspective, of course. }} completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); } {{else}} ^(NSError * _Nullable error) { @@ -138,14 +138,13 @@ completionHandler type-safety perspective, of course. }} completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); } {{/if}} ]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index b0274760046165..7fdbe9367c7ece 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -82,8 +82,8 @@ - (void)identifyWithParams:(MTRIdentifyClusterIdentifyParams *)params expectedVa // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:baseDevice @@ -95,12 +95,11 @@ - (void)identifyWithParams:(MTRIdentifyClusterIdentifyParams *)params expectedVa dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -118,8 +117,8 @@ - (void)triggerEffectWithParams:(MTRIdentifyClusterTriggerEffectParams *)params // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:baseDevice @@ -131,12 +130,11 @@ - (void)triggerEffectWithParams:(MTRIdentifyClusterTriggerEffectParams *)params dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -240,8 +238,8 @@ - (void)addGroupWithParams:(MTRGroupsClusterAddGroupParams *)params expectedValu // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:baseDevice @@ -253,12 +251,11 @@ - (void)addGroupWithParams:(MTRGroupsClusterAddGroupParams *)params expectedValu dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -276,8 +273,8 @@ - (void)viewGroupWithParams:(MTRGroupsClusterViewGroupParams *)params expectedVa // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:baseDevice @@ -289,12 +286,11 @@ - (void)viewGroupWithParams:(MTRGroupsClusterViewGroupParams *)params expectedVa dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -312,8 +308,8 @@ - (void)getGroupMembershipWithParams:(MTRGroupsClusterGetGroupMembershipParams * // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:baseDevice @@ -325,12 +321,11 @@ - (void)getGroupMembershipWithParams:(MTRGroupsClusterGetGroupMembershipParams * dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -348,8 +343,8 @@ - (void)removeGroupWithParams:(MTRGroupsClusterRemoveGroupParams *)params expect // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:baseDevice @@ -361,12 +356,11 @@ - (void)removeGroupWithParams:(MTRGroupsClusterRemoveGroupParams *)params expect dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -388,8 +382,8 @@ - (void)removeAllGroupsWithParams:(MTRGroupsClusterRemoveAllGroupsParams * _Null // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:baseDevice @@ -401,12 +395,11 @@ - (void)removeAllGroupsWithParams:(MTRGroupsClusterRemoveAllGroupsParams * _Null dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -424,8 +417,8 @@ - (void)addGroupIfIdentifyingWithParams:(MTRGroupsClusterAddGroupIfIdentifyingPa // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:baseDevice @@ -437,12 +430,11 @@ - (void)addGroupIfIdentifyingWithParams:(MTRGroupsClusterAddGroupIfIdentifyingPa dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -566,8 +558,8 @@ - (void)addSceneWithParams:(MTRScenesClusterAddSceneParams *)params expectedValu // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:baseDevice @@ -579,12 +571,11 @@ - (void)addSceneWithParams:(MTRScenesClusterAddSceneParams *)params expectedValu dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -602,8 +593,8 @@ - (void)viewSceneWithParams:(MTRScenesClusterViewSceneParams *)params expectedVa // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:baseDevice @@ -615,12 +606,11 @@ - (void)viewSceneWithParams:(MTRScenesClusterViewSceneParams *)params expectedVa dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -638,8 +628,8 @@ - (void)removeSceneWithParams:(MTRScenesClusterRemoveSceneParams *)params expect // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:baseDevice @@ -651,12 +641,11 @@ - (void)removeSceneWithParams:(MTRScenesClusterRemoveSceneParams *)params expect dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -674,8 +663,8 @@ - (void)removeAllScenesWithParams:(MTRScenesClusterRemoveAllScenesParams *)param // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:baseDevice @@ -687,12 +676,11 @@ - (void)removeAllScenesWithParams:(MTRScenesClusterRemoveAllScenesParams *)param dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -710,8 +698,8 @@ - (void)storeSceneWithParams:(MTRScenesClusterStoreSceneParams *)params expected // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:baseDevice @@ -723,12 +711,11 @@ - (void)storeSceneWithParams:(MTRScenesClusterStoreSceneParams *)params expected dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -746,8 +733,8 @@ - (void)recallSceneWithParams:(MTRScenesClusterRecallSceneParams *)params expect // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:baseDevice @@ -759,12 +746,11 @@ - (void)recallSceneWithParams:(MTRScenesClusterRecallSceneParams *)params expect dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -782,8 +768,8 @@ - (void)getSceneMembershipWithParams:(MTRScenesClusterGetSceneMembershipParams * // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:baseDevice @@ -795,12 +781,11 @@ - (void)getSceneMembershipWithParams:(MTRScenesClusterGetSceneMembershipParams * dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -818,8 +803,8 @@ - (void)enhancedAddSceneWithParams:(MTRScenesClusterEnhancedAddSceneParams *)par // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:baseDevice @@ -831,12 +816,11 @@ - (void)enhancedAddSceneWithParams:(MTRScenesClusterEnhancedAddSceneParams *)par dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -854,8 +838,8 @@ - (void)enhancedViewSceneWithParams:(MTRScenesClusterEnhancedViewSceneParams *)p // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:baseDevice @@ -867,12 +851,11 @@ - (void)enhancedViewSceneWithParams:(MTRScenesClusterEnhancedViewSceneParams *)p dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -890,8 +873,8 @@ - (void)copySceneWithParams:(MTRScenesClusterCopySceneParams *)params expectedVa // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:baseDevice @@ -903,12 +886,11 @@ - (void)copySceneWithParams:(MTRScenesClusterCopySceneParams *)params expectedVa dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -1102,8 +1084,8 @@ - (void)offWithParams:(MTROnOffClusterOffParams * _Nullable)params expectedValue // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:baseDevice @@ -1115,12 +1097,11 @@ - (void)offWithParams:(MTROnOffClusterOffParams * _Nullable)params expectedValue dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -1142,8 +1123,8 @@ - (void)onWithParams:(MTROnOffClusterOnParams * _Nullable)params expectedValues: // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:baseDevice @@ -1155,12 +1136,11 @@ - (void)onWithParams:(MTROnOffClusterOnParams * _Nullable)params expectedValues: dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -1182,8 +1162,8 @@ - (void)toggleWithParams:(MTROnOffClusterToggleParams * _Nullable)params expecte // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:baseDevice @@ -1195,12 +1175,11 @@ - (void)toggleWithParams:(MTROnOffClusterToggleParams * _Nullable)params expecte dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -1218,8 +1197,8 @@ - (void)offWithEffectWithParams:(MTROnOffClusterOffWithEffectParams *)params exp // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:baseDevice @@ -1231,12 +1210,11 @@ - (void)offWithEffectWithParams:(MTROnOffClusterOffWithEffectParams *)params exp dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -1258,8 +1236,8 @@ - (void)onWithRecallGlobalSceneWithParams:(MTROnOffClusterOnWithRecallGlobalScen // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:baseDevice @@ -1271,12 +1249,11 @@ - (void)onWithRecallGlobalSceneWithParams:(MTROnOffClusterOnWithRecallGlobalScen dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -1294,8 +1271,8 @@ - (void)onWithTimedOffWithParams:(MTROnOffClusterOnWithTimedOffParams *)params e // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:baseDevice @@ -1307,12 +1284,11 @@ - (void)onWithTimedOffWithParams:(MTROnOffClusterOnWithTimedOffParams *)params e dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -1565,8 +1541,8 @@ - (void)moveToLevelWithParams:(MTRLevelControlClusterMoveToLevelParams *)params // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:baseDevice @@ -1578,12 +1554,11 @@ - (void)moveToLevelWithParams:(MTRLevelControlClusterMoveToLevelParams *)params dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -1601,8 +1576,8 @@ - (void)moveWithParams:(MTRLevelControlClusterMoveParams *)params expectedValues // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:baseDevice @@ -1614,12 +1589,11 @@ - (void)moveWithParams:(MTRLevelControlClusterMoveParams *)params expectedValues dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -1637,8 +1611,8 @@ - (void)stepWithParams:(MTRLevelControlClusterStepParams *)params expectedValues // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:baseDevice @@ -1650,12 +1624,11 @@ - (void)stepWithParams:(MTRLevelControlClusterStepParams *)params expectedValues dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -1673,8 +1646,8 @@ - (void)stopWithParams:(MTRLevelControlClusterStopParams *)params expectedValues // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:baseDevice @@ -1686,12 +1659,11 @@ - (void)stopWithParams:(MTRLevelControlClusterStopParams *)params expectedValues dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -1709,8 +1681,8 @@ - (void)moveToLevelWithOnOffWithParams:(MTRLevelControlClusterMoveToLevelWithOnO // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:baseDevice @@ -1722,12 +1694,11 @@ - (void)moveToLevelWithOnOffWithParams:(MTRLevelControlClusterMoveToLevelWithOnO dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -1745,8 +1716,8 @@ - (void)moveWithOnOffWithParams:(MTRLevelControlClusterMoveWithOnOffParams *)par // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:baseDevice @@ -1758,12 +1729,11 @@ - (void)moveWithOnOffWithParams:(MTRLevelControlClusterMoveWithOnOffParams *)par dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -1781,8 +1751,8 @@ - (void)stepWithOnOffWithParams:(MTRLevelControlClusterStepWithOnOffParams *)par // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:baseDevice @@ -1794,12 +1764,11 @@ - (void)stepWithOnOffWithParams:(MTRLevelControlClusterStepWithOnOffParams *)par dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -1817,8 +1786,8 @@ - (void)stopWithOnOffWithParams:(MTRLevelControlClusterStopWithOnOffParams *)par // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:baseDevice @@ -1830,12 +1799,11 @@ - (void)stopWithOnOffWithParams:(MTRLevelControlClusterStopWithOnOffParams *)par dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -1853,8 +1821,8 @@ - (void)moveToClosestFrequencyWithParams:(MTRLevelControlClusterMoveToClosestFre // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:baseDevice @@ -1866,12 +1834,11 @@ - (void)moveToClosestFrequencyWithParams:(MTRLevelControlClusterMoveToClosestFre dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -2617,8 +2584,8 @@ - (void)instantActionWithParams:(MTRActionsClusterInstantActionParams *)params e // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterActions alloc] initWithDevice:baseDevice @@ -2630,12 +2597,11 @@ - (void)instantActionWithParams:(MTRActionsClusterInstantActionParams *)params e dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -2653,8 +2619,8 @@ - (void)instantActionWithTransitionWithParams:(MTRActionsClusterInstantActionWit // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterActions alloc] initWithDevice:baseDevice @@ -2666,12 +2632,11 @@ - (void)instantActionWithTransitionWithParams:(MTRActionsClusterInstantActionWit dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -2689,8 +2654,8 @@ - (void)startActionWithParams:(MTRActionsClusterStartActionParams *)params expec // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterActions alloc] initWithDevice:baseDevice @@ -2702,12 +2667,11 @@ - (void)startActionWithParams:(MTRActionsClusterStartActionParams *)params expec dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -2725,8 +2689,8 @@ - (void)startActionWithDurationWithParams:(MTRActionsClusterStartActionWithDurat // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterActions alloc] initWithDevice:baseDevice @@ -2738,12 +2702,11 @@ - (void)startActionWithDurationWithParams:(MTRActionsClusterStartActionWithDurat dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -2761,8 +2724,8 @@ - (void)stopActionWithParams:(MTRActionsClusterStopActionParams *)params expecte // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterActions alloc] initWithDevice:baseDevice @@ -2774,12 +2737,11 @@ - (void)stopActionWithParams:(MTRActionsClusterStopActionParams *)params expecte dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -2797,8 +2759,8 @@ - (void)pauseActionWithParams:(MTRActionsClusterPauseActionParams *)params expec // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterActions alloc] initWithDevice:baseDevice @@ -2810,12 +2772,11 @@ - (void)pauseActionWithParams:(MTRActionsClusterPauseActionParams *)params expec dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -2833,8 +2794,8 @@ - (void)pauseActionWithDurationWithParams:(MTRActionsClusterPauseActionWithDurat // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterActions alloc] initWithDevice:baseDevice @@ -2846,12 +2807,11 @@ - (void)pauseActionWithDurationWithParams:(MTRActionsClusterPauseActionWithDurat dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -2869,8 +2829,8 @@ - (void)resumeActionWithParams:(MTRActionsClusterResumeActionParams *)params exp // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterActions alloc] initWithDevice:baseDevice @@ -2882,12 +2842,11 @@ - (void)resumeActionWithParams:(MTRActionsClusterResumeActionParams *)params exp dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -2905,8 +2864,8 @@ - (void)enableActionWithParams:(MTRActionsClusterEnableActionParams *)params exp // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterActions alloc] initWithDevice:baseDevice @@ -2918,12 +2877,11 @@ - (void)enableActionWithParams:(MTRActionsClusterEnableActionParams *)params exp dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -2941,8 +2899,8 @@ - (void)enableActionWithDurationWithParams:(MTRActionsClusterEnableActionWithDur // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterActions alloc] initWithDevice:baseDevice @@ -2954,12 +2912,11 @@ - (void)enableActionWithDurationWithParams:(MTRActionsClusterEnableActionWithDur dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -2977,8 +2934,8 @@ - (void)disableActionWithParams:(MTRActionsClusterDisableActionParams *)params e // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterActions alloc] initWithDevice:baseDevice @@ -2990,12 +2947,11 @@ - (void)disableActionWithParams:(MTRActionsClusterDisableActionParams *)params e dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -3013,8 +2969,8 @@ - (void)disableActionWithDurationWithParams:(MTRActionsClusterDisableActionWithD // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterActions alloc] initWithDevice:baseDevice @@ -3026,12 +2982,11 @@ - (void)disableActionWithDurationWithParams:(MTRActionsClusterDisableActionWithD dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -3183,8 +3138,8 @@ - (void)mfgSpecificPingWithParams:(MTRBasicClusterMfgSpecificPingParams * _Nulla // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterBasic alloc] initWithDevice:baseDevice @@ -3196,12 +3151,11 @@ - (void)mfgSpecificPingWithParams:(MTRBasicClusterMfgSpecificPingParams * _Nulla dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -3423,8 +3377,8 @@ - (void)queryImageWithParams:(MTROTASoftwareUpdateProviderClusterQueryImageParam // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOTASoftwareUpdateProvider alloc] initWithDevice:baseDevice @@ -3436,12 +3390,11 @@ - (void)queryImageWithParams:(MTROTASoftwareUpdateProviderClusterQueryImageParam dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -3459,8 +3412,8 @@ - (void)applyUpdateRequestWithParams:(MTROTASoftwareUpdateProviderClusterApplyUp // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOTASoftwareUpdateProvider alloc] initWithDevice:baseDevice @@ -3472,12 +3425,11 @@ - (void)applyUpdateRequestWithParams:(MTROTASoftwareUpdateProviderClusterApplyUp dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -3495,8 +3447,8 @@ - (void)notifyUpdateAppliedWithParams:(MTROTASoftwareUpdateProviderClusterNotify // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOTASoftwareUpdateProvider alloc] initWithDevice:baseDevice @@ -3508,12 +3460,11 @@ - (void)notifyUpdateAppliedWithParams:(MTROTASoftwareUpdateProviderClusterNotify dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -3609,8 +3560,8 @@ - (void)announceOTAProviderWithParams:(MTROTASoftwareUpdateRequestorClusterAnnou // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:baseDevice @@ -3622,12 +3573,11 @@ - (void)announceOTAProviderWithParams:(MTROTASoftwareUpdateRequestorClusterAnnou dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -4264,8 +4214,8 @@ - (void)armFailSafeWithParams:(MTRGeneralCommissioningClusterArmFailSafeParams * // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:baseDevice @@ -4277,12 +4227,11 @@ - (void)armFailSafeWithParams:(MTRGeneralCommissioningClusterArmFailSafeParams * dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -4300,8 +4249,8 @@ - (void)setRegulatoryConfigWithParams:(MTRGeneralCommissioningClusterSetRegulato // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:baseDevice @@ -4313,12 +4262,11 @@ - (void)setRegulatoryConfigWithParams:(MTRGeneralCommissioningClusterSetRegulato dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -4340,8 +4288,8 @@ - (void)commissioningCompleteWithParams:(MTRGeneralCommissioningClusterCommissio // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:baseDevice @@ -4353,12 +4301,11 @@ - (void)commissioningCompleteWithParams:(MTRGeneralCommissioningClusterCommissio dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -4495,8 +4442,8 @@ - (void)scanNetworksWithParams:(MTRNetworkCommissioningClusterScanNetworksParams // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:baseDevice @@ -4508,12 +4455,11 @@ - (void)scanNetworksWithParams:(MTRNetworkCommissioningClusterScanNetworksParams dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -4531,8 +4477,8 @@ - (void)addOrUpdateWiFiNetworkWithParams:(MTRNetworkCommissioningClusterAddOrUpd // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:baseDevice @@ -4544,12 +4490,11 @@ - (void)addOrUpdateWiFiNetworkWithParams:(MTRNetworkCommissioningClusterAddOrUpd dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -4567,8 +4512,8 @@ - (void)addOrUpdateThreadNetworkWithParams:(MTRNetworkCommissioningClusterAddOrU // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:baseDevice @@ -4580,12 +4525,11 @@ - (void)addOrUpdateThreadNetworkWithParams:(MTRNetworkCommissioningClusterAddOrU dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -4603,8 +4547,8 @@ - (void)removeNetworkWithParams:(MTRNetworkCommissioningClusterRemoveNetworkPara // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:baseDevice @@ -4616,12 +4560,11 @@ - (void)removeNetworkWithParams:(MTRNetworkCommissioningClusterRemoveNetworkPara dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -4639,8 +4582,8 @@ - (void)connectNetworkWithParams:(MTRNetworkCommissioningClusterConnectNetworkPa // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:baseDevice @@ -4652,12 +4595,11 @@ - (void)connectNetworkWithParams:(MTRNetworkCommissioningClusterConnectNetworkPa dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -4675,8 +4617,8 @@ - (void)reorderNetworkWithParams:(MTRNetworkCommissioningClusterReorderNetworkPa // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:baseDevice @@ -4688,12 +4630,11 @@ - (void)reorderNetworkWithParams:(MTRNetworkCommissioningClusterReorderNetworkPa dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -4865,8 +4806,8 @@ - (void)retrieveLogsRequestWithParams:(MTRDiagnosticLogsClusterRetrieveLogsReque // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDiagnosticLogs alloc] initWithDevice:baseDevice @@ -4878,12 +4819,11 @@ - (void)retrieveLogsRequestWithParams:(MTRDiagnosticLogsClusterRetrieveLogsReque dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -4964,8 +4904,8 @@ - (void)testEventTriggerWithParams:(MTRGeneralDiagnosticsClusterTestEventTrigger // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:baseDevice @@ -4977,12 +4917,11 @@ - (void)testEventTriggerWithParams:(MTRGeneralDiagnosticsClusterTestEventTrigger dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -5118,8 +5057,8 @@ - (void)resetWatermarksWithParams:(MTRSoftwareDiagnosticsClusterResetWatermarksP // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:baseDevice @@ -5131,12 +5070,11 @@ - (void)resetWatermarksWithParams:(MTRSoftwareDiagnosticsClusterResetWatermarksP dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -5242,8 +5180,8 @@ - (void)resetCountsWithParams:(MTRThreadNetworkDiagnosticsClusterResetCountsPara // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:baseDevice @@ -5255,12 +5193,11 @@ - (void)resetCountsWithParams:(MTRThreadNetworkDiagnosticsClusterResetCountsPara dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -5669,8 +5606,8 @@ - (void)resetCountsWithParams:(MTRWiFiNetworkDiagnosticsClusterResetCountsParams // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:baseDevice @@ -5682,12 +5619,11 @@ - (void)resetCountsWithParams:(MTRWiFiNetworkDiagnosticsClusterResetCountsParams dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -5846,8 +5782,8 @@ - (void)resetCountsWithParams:(MTREthernetNetworkDiagnosticsClusterResetCountsPa // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:baseDevice @@ -5859,12 +5795,11 @@ - (void)resetCountsWithParams:(MTREthernetNetworkDiagnosticsClusterResetCountsPa dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -5991,8 +5926,8 @@ - (void)setUTCTimeWithParams:(MTRTimeSynchronizationClusterSetUTCTimeParams *)pa // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterTimeSynchronization alloc] initWithDevice:baseDevice @@ -6004,12 +5939,11 @@ - (void)setUTCTimeWithParams:(MTRTimeSynchronizationClusterSetUTCTimeParams *)pa dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -6027,8 +5961,8 @@ - (void)setTrustedTimeSourceWithParams:(MTRTimeSynchronizationClusterSetTrustedT // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterTimeSynchronization alloc] initWithDevice:baseDevice @@ -6040,12 +5974,11 @@ - (void)setTrustedTimeSourceWithParams:(MTRTimeSynchronizationClusterSetTrustedT dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -6063,8 +5996,8 @@ - (void)setTimeZoneWithParams:(MTRTimeSynchronizationClusterSetTimeZoneParams *) // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterTimeSynchronization alloc] initWithDevice:baseDevice @@ -6076,12 +6009,11 @@ - (void)setTimeZoneWithParams:(MTRTimeSynchronizationClusterSetTimeZoneParams *) dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -6099,8 +6031,8 @@ - (void)setDSTOffsetWithParams:(MTRTimeSynchronizationClusterSetDSTOffsetParams // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterTimeSynchronization alloc] initWithDevice:baseDevice @@ -6112,12 +6044,11 @@ - (void)setDSTOffsetWithParams:(MTRTimeSynchronizationClusterSetDSTOffsetParams dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -6135,8 +6066,8 @@ - (void)setDefaultNTPWithParams:(MTRTimeSynchronizationClusterSetDefaultNTPParam // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterTimeSynchronization alloc] initWithDevice:baseDevice @@ -6148,12 +6079,11 @@ - (void)setDefaultNTPWithParams:(MTRTimeSynchronizationClusterSetDefaultNTPParam dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -6500,8 +6430,8 @@ - (void)openCommissioningWindowWithParams:(MTRAdministratorCommissioningClusterO // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:baseDevice @@ -6513,12 +6443,11 @@ - (void)openCommissioningWindowWithParams:(MTRAdministratorCommissioningClusterO dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -6536,8 +6465,8 @@ - (void)openBasicCommissioningWindowWithParams:(MTRAdministratorCommissioningClu // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:baseDevice @@ -6549,12 +6478,11 @@ - (void)openBasicCommissioningWindowWithParams:(MTRAdministratorCommissioningClu dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -6576,8 +6504,8 @@ - (void)revokeCommissioningWithParams:(MTRAdministratorCommissioningClusterRevok // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:baseDevice @@ -6589,12 +6517,11 @@ - (void)revokeCommissioningWithParams:(MTRAdministratorCommissioningClusterRevok dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -6701,8 +6628,8 @@ - (void)attestationRequestWithParams:(MTROperationalCredentialsClusterAttestatio // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:baseDevice @@ -6714,12 +6641,11 @@ - (void)attestationRequestWithParams:(MTROperationalCredentialsClusterAttestatio dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -6737,8 +6663,8 @@ - (void)certificateChainRequestWithParams:(MTROperationalCredentialsClusterCerti // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:baseDevice @@ -6750,12 +6676,11 @@ - (void)certificateChainRequestWithParams:(MTROperationalCredentialsClusterCerti dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -6773,8 +6698,8 @@ - (void)CSRRequestWithParams:(MTROperationalCredentialsClusterCSRRequestParams * // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:baseDevice @@ -6786,12 +6711,11 @@ - (void)CSRRequestWithParams:(MTROperationalCredentialsClusterCSRRequestParams * dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -6809,8 +6733,8 @@ - (void)addNOCWithParams:(MTROperationalCredentialsClusterAddNOCParams *)params // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:baseDevice @@ -6822,12 +6746,11 @@ - (void)addNOCWithParams:(MTROperationalCredentialsClusterAddNOCParams *)params dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -6845,8 +6768,8 @@ - (void)updateNOCWithParams:(MTROperationalCredentialsClusterUpdateNOCParams *)p // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:baseDevice @@ -6858,12 +6781,11 @@ - (void)updateNOCWithParams:(MTROperationalCredentialsClusterUpdateNOCParams *)p dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -6881,8 +6803,8 @@ - (void)updateFabricLabelWithParams:(MTROperationalCredentialsClusterUpdateFabri // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:baseDevice @@ -6894,12 +6816,11 @@ - (void)updateFabricLabelWithParams:(MTROperationalCredentialsClusterUpdateFabri dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -6917,8 +6838,8 @@ - (void)removeFabricWithParams:(MTROperationalCredentialsClusterRemoveFabricPara // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:baseDevice @@ -6930,12 +6851,11 @@ - (void)removeFabricWithParams:(MTROperationalCredentialsClusterRemoveFabricPara dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -6953,8 +6873,8 @@ - (void)addTrustedRootCertificateWithParams:(MTROperationalCredentialsClusterAdd // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:baseDevice @@ -6966,12 +6886,11 @@ - (void)addTrustedRootCertificateWithParams:(MTROperationalCredentialsClusterAdd dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -7135,8 +7054,8 @@ - (void)keySetWriteWithParams:(MTRGroupKeyManagementClusterKeySetWriteParams *)p // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:baseDevice @@ -7148,12 +7067,11 @@ - (void)keySetWriteWithParams:(MTRGroupKeyManagementClusterKeySetWriteParams *)p dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -7171,8 +7089,8 @@ - (void)keySetReadWithParams:(MTRGroupKeyManagementClusterKeySetReadParams *)par // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:baseDevice @@ -7184,12 +7102,11 @@ - (void)keySetReadWithParams:(MTRGroupKeyManagementClusterKeySetReadParams *)par dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -7207,8 +7124,8 @@ - (void)keySetRemoveWithParams:(MTRGroupKeyManagementClusterKeySetRemoveParams * // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:baseDevice @@ -7220,12 +7137,11 @@ - (void)keySetRemoveWithParams:(MTRGroupKeyManagementClusterKeySetRemoveParams * dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -7247,8 +7163,8 @@ - (void)keySetReadAllIndicesWithParams:(MTRGroupKeyManagementClusterKeySetReadAl // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:baseDevice @@ -7260,12 +7176,11 @@ - (void)keySetReadAllIndicesWithParams:(MTRGroupKeyManagementClusterKeySetReadAl dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -7586,8 +7501,8 @@ - (void)registerClientWithParams:(MTRICDManagementClusterRegisterClientParams *) // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:baseDevice @@ -7599,12 +7514,11 @@ - (void)registerClientWithParams:(MTRICDManagementClusterRegisterClientParams *) dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -7622,8 +7536,8 @@ - (void)unregisterClientWithParams:(MTRICDManagementClusterUnregisterClientParam // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:baseDevice @@ -7635,12 +7549,11 @@ - (void)unregisterClientWithParams:(MTRICDManagementClusterUnregisterClientParam dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -7662,8 +7575,8 @@ - (void)stayActiveRequestWithParams:(MTRICDManagementClusterStayActiveRequestPar // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:baseDevice @@ -7675,12 +7588,11 @@ - (void)stayActiveRequestWithParams:(MTRICDManagementClusterStayActiveRequestPar dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -7774,8 +7686,8 @@ - (void)changeToModeWithParams:(MTRModeSelectClusterChangeToModeParams *)params // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:baseDevice @@ -7787,12 +7699,11 @@ - (void)changeToModeWithParams:(MTRModeSelectClusterChangeToModeParams *)params dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -7922,8 +7833,8 @@ - (void)changeToModeWithParams:(MTRLaundryWasherModeClusterChangeToModeParams *) // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterLaundryWasherMode alloc] initWithDevice:baseDevice @@ -7935,12 +7846,11 @@ - (void)changeToModeWithParams:(MTRLaundryWasherModeClusterChangeToModeParams *) dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -8046,8 +7956,8 @@ - (void)changeToModeWithParams:(MTRRefrigeratorAndTemperatureControlledCabinetMo // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterRefrigeratorAndTemperatureControlledCabinetMode alloc] initWithDevice:baseDevice @@ -8059,12 +7969,11 @@ - (void)changeToModeWithParams:(MTRRefrigeratorAndTemperatureControlledCabinetMo dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -8258,8 +8167,8 @@ - (void)changeToModeWithParams:(MTRRVCRunModeClusterChangeToModeParams *)params // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterRVCRunMode alloc] initWithDevice:baseDevice @@ -8271,12 +8180,11 @@ - (void)changeToModeWithParams:(MTRRVCRunModeClusterChangeToModeParams *)params dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -8382,8 +8290,8 @@ - (void)changeToModeWithParams:(MTRRVCCleanModeClusterChangeToModeParams *)param // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterRVCCleanMode alloc] initWithDevice:baseDevice @@ -8395,12 +8303,11 @@ - (void)changeToModeWithParams:(MTRRVCCleanModeClusterChangeToModeParams *)param dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -8506,8 +8413,8 @@ - (void)setTemperatureWithParams:(MTRTemperatureControlClusterSetTemperaturePara // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterTemperatureControl alloc] initWithDevice:baseDevice @@ -8519,12 +8426,11 @@ - (void)setTemperatureWithParams:(MTRTemperatureControlClusterSetTemperaturePara dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -8679,8 +8585,8 @@ - (void)changeToModeWithParams:(MTRDishwasherModeClusterChangeToModeParams *)par // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDishwasherMode alloc] initWithDevice:baseDevice @@ -8692,12 +8598,11 @@ - (void)changeToModeWithParams:(MTRDishwasherModeClusterChangeToModeParams *)par dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -8858,8 +8763,8 @@ - (void)selfTestRequestWithParams:(MTRSmokeCOAlarmClusterSelfTestRequestParams * // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterSmokeCOAlarm alloc] initWithDevice:baseDevice @@ -8871,12 +8776,11 @@ - (void)selfTestRequestWithParams:(MTRSmokeCOAlarmClusterSelfTestRequestParams * dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -9016,8 +8920,8 @@ - (void)resetWithParams:(MTRDishwasherAlarmClusterResetParams *)params expectedV // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:baseDevice @@ -9029,12 +8933,11 @@ - (void)resetWithParams:(MTRDishwasherAlarmClusterResetParams *)params expectedV dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -9052,8 +8955,8 @@ - (void)modifyEnabledAlarmsWithParams:(MTRDishwasherAlarmClusterModifyEnabledAla // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:baseDevice @@ -9065,12 +8968,11 @@ - (void)modifyEnabledAlarmsWithParams:(MTRDishwasherAlarmClusterModifyEnabledAla dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -9158,8 +9060,8 @@ - (void)pauseWithParams:(MTROperationalStateClusterPauseParams * _Nullable)param // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOperationalState alloc] initWithDevice:baseDevice @@ -9171,12 +9073,11 @@ - (void)pauseWithParams:(MTROperationalStateClusterPauseParams * _Nullable)param dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -9198,8 +9099,8 @@ - (void)stopWithParams:(MTROperationalStateClusterStopParams * _Nullable)params // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOperationalState alloc] initWithDevice:baseDevice @@ -9211,12 +9112,11 @@ - (void)stopWithParams:(MTROperationalStateClusterStopParams * _Nullable)params dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -9238,8 +9138,8 @@ - (void)startWithParams:(MTROperationalStateClusterStartParams * _Nullable)param // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOperationalState alloc] initWithDevice:baseDevice @@ -9251,12 +9151,11 @@ - (void)startWithParams:(MTROperationalStateClusterStartParams * _Nullable)param dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -9278,8 +9177,8 @@ - (void)resumeWithParams:(MTROperationalStateClusterResumeParams * _Nullable)par // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterOperationalState alloc] initWithDevice:baseDevice @@ -9291,12 +9190,11 @@ - (void)resumeWithParams:(MTROperationalStateClusterResumeParams * _Nullable)par dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -9394,8 +9292,8 @@ - (void)pauseWithParams:(MTRRVCOperationalStateClusterPauseParams * _Nullable)pa // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterRVCOperationalState alloc] initWithDevice:baseDevice @@ -9407,12 +9305,11 @@ - (void)pauseWithParams:(MTRRVCOperationalStateClusterPauseParams * _Nullable)pa dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -9434,8 +9331,8 @@ - (void)stopWithParams:(MTRRVCOperationalStateClusterStopParams * _Nullable)para // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterRVCOperationalState alloc] initWithDevice:baseDevice @@ -9447,12 +9344,11 @@ - (void)stopWithParams:(MTRRVCOperationalStateClusterStopParams * _Nullable)para dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -9474,8 +9370,8 @@ - (void)startWithParams:(MTRRVCOperationalStateClusterStartParams * _Nullable)pa // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterRVCOperationalState alloc] initWithDevice:baseDevice @@ -9487,12 +9383,11 @@ - (void)startWithParams:(MTRRVCOperationalStateClusterStartParams * _Nullable)pa dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -9514,8 +9409,8 @@ - (void)resumeWithParams:(MTRRVCOperationalStateClusterResumeParams * _Nullable) // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterRVCOperationalState alloc] initWithDevice:baseDevice @@ -9527,12 +9422,11 @@ - (void)resumeWithParams:(MTRRVCOperationalStateClusterResumeParams * _Nullable) dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -9630,8 +9524,8 @@ - (void)resetConditionWithParams:(MTRHEPAFilterMonitoringClusterResetConditionPa // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:baseDevice @@ -9643,12 +9537,11 @@ - (void)resetConditionWithParams:(MTRHEPAFilterMonitoringClusterResetConditionPa dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -9757,8 +9650,8 @@ - (void)resetConditionWithParams:(MTRActivatedCarbonFilterMonitoringClusterReset // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:baseDevice @@ -9770,12 +9663,11 @@ - (void)resetConditionWithParams:(MTRActivatedCarbonFilterMonitoringClusterReset dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -9880,8 +9772,8 @@ - (void)lockDoorWithParams:(MTRDoorLockClusterLockDoorParams * _Nullable)params // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:baseDevice @@ -9893,12 +9785,11 @@ - (void)lockDoorWithParams:(MTRDoorLockClusterLockDoorParams * _Nullable)params dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -9916,8 +9807,8 @@ - (void)unlockDoorWithParams:(MTRDoorLockClusterUnlockDoorParams * _Nullable)par // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:baseDevice @@ -9929,12 +9820,11 @@ - (void)unlockDoorWithParams:(MTRDoorLockClusterUnlockDoorParams * _Nullable)par dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -9952,8 +9842,8 @@ - (void)unlockWithTimeoutWithParams:(MTRDoorLockClusterUnlockWithTimeoutParams * // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:baseDevice @@ -9965,12 +9855,11 @@ - (void)unlockWithTimeoutWithParams:(MTRDoorLockClusterUnlockWithTimeoutParams * dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -9988,8 +9877,8 @@ - (void)setWeekDayScheduleWithParams:(MTRDoorLockClusterSetWeekDayScheduleParams // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:baseDevice @@ -10001,12 +9890,11 @@ - (void)setWeekDayScheduleWithParams:(MTRDoorLockClusterSetWeekDayScheduleParams dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -10024,8 +9912,8 @@ - (void)getWeekDayScheduleWithParams:(MTRDoorLockClusterGetWeekDayScheduleParams // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:baseDevice @@ -10037,12 +9925,11 @@ - (void)getWeekDayScheduleWithParams:(MTRDoorLockClusterGetWeekDayScheduleParams dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -10060,8 +9947,8 @@ - (void)clearWeekDayScheduleWithParams:(MTRDoorLockClusterClearWeekDaySchedulePa // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:baseDevice @@ -10073,12 +9960,11 @@ - (void)clearWeekDayScheduleWithParams:(MTRDoorLockClusterClearWeekDaySchedulePa dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -10096,8 +9982,8 @@ - (void)setYearDayScheduleWithParams:(MTRDoorLockClusterSetYearDayScheduleParams // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:baseDevice @@ -10109,12 +9995,11 @@ - (void)setYearDayScheduleWithParams:(MTRDoorLockClusterSetYearDayScheduleParams dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -10132,8 +10017,8 @@ - (void)getYearDayScheduleWithParams:(MTRDoorLockClusterGetYearDayScheduleParams // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:baseDevice @@ -10145,12 +10030,11 @@ - (void)getYearDayScheduleWithParams:(MTRDoorLockClusterGetYearDayScheduleParams dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -10168,8 +10052,8 @@ - (void)clearYearDayScheduleWithParams:(MTRDoorLockClusterClearYearDaySchedulePa // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:baseDevice @@ -10181,12 +10065,11 @@ - (void)clearYearDayScheduleWithParams:(MTRDoorLockClusterClearYearDaySchedulePa dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -10204,8 +10087,8 @@ - (void)setHolidayScheduleWithParams:(MTRDoorLockClusterSetHolidayScheduleParams // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:baseDevice @@ -10217,12 +10100,11 @@ - (void)setHolidayScheduleWithParams:(MTRDoorLockClusterSetHolidayScheduleParams dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -10240,8 +10122,8 @@ - (void)getHolidayScheduleWithParams:(MTRDoorLockClusterGetHolidayScheduleParams // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:baseDevice @@ -10253,12 +10135,11 @@ - (void)getHolidayScheduleWithParams:(MTRDoorLockClusterGetHolidayScheduleParams dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -10276,8 +10157,8 @@ - (void)clearHolidayScheduleWithParams:(MTRDoorLockClusterClearHolidaySchedulePa // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:baseDevice @@ -10289,12 +10170,11 @@ - (void)clearHolidayScheduleWithParams:(MTRDoorLockClusterClearHolidaySchedulePa dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -10312,8 +10192,8 @@ - (void)setUserWithParams:(MTRDoorLockClusterSetUserParams *)params expectedValu // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:baseDevice @@ -10325,12 +10205,11 @@ - (void)setUserWithParams:(MTRDoorLockClusterSetUserParams *)params expectedValu dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -10348,8 +10227,8 @@ - (void)getUserWithParams:(MTRDoorLockClusterGetUserParams *)params expectedValu // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:baseDevice @@ -10361,12 +10240,11 @@ - (void)getUserWithParams:(MTRDoorLockClusterGetUserParams *)params expectedValu dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -10384,8 +10262,8 @@ - (void)clearUserWithParams:(MTRDoorLockClusterClearUserParams *)params expected // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:baseDevice @@ -10397,12 +10275,11 @@ - (void)clearUserWithParams:(MTRDoorLockClusterClearUserParams *)params expected dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -10420,8 +10297,8 @@ - (void)setCredentialWithParams:(MTRDoorLockClusterSetCredentialParams *)params // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:baseDevice @@ -10433,12 +10310,11 @@ - (void)setCredentialWithParams:(MTRDoorLockClusterSetCredentialParams *)params dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -10456,8 +10332,8 @@ - (void)getCredentialStatusWithParams:(MTRDoorLockClusterGetCredentialStatusPara // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:baseDevice @@ -10469,12 +10345,11 @@ - (void)getCredentialStatusWithParams:(MTRDoorLockClusterGetCredentialStatusPara dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -10492,8 +10367,8 @@ - (void)clearCredentialWithParams:(MTRDoorLockClusterClearCredentialParams *)par // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:baseDevice @@ -10505,12 +10380,11 @@ - (void)clearCredentialWithParams:(MTRDoorLockClusterClearCredentialParams *)par dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -10528,8 +10402,8 @@ - (void)unboltDoorWithParams:(MTRDoorLockClusterUnboltDoorParams * _Nullable)par // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:baseDevice @@ -10541,12 +10415,11 @@ - (void)unboltDoorWithParams:(MTRDoorLockClusterUnboltDoorParams * _Nullable)par dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -11109,8 +10982,8 @@ - (void)upOrOpenWithParams:(MTRWindowCoveringClusterUpOrOpenParams * _Nullable)p // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:baseDevice @@ -11122,12 +10995,11 @@ - (void)upOrOpenWithParams:(MTRWindowCoveringClusterUpOrOpenParams * _Nullable)p dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -11149,8 +11021,8 @@ - (void)downOrCloseWithParams:(MTRWindowCoveringClusterDownOrCloseParams * _Null // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:baseDevice @@ -11162,12 +11034,11 @@ - (void)downOrCloseWithParams:(MTRWindowCoveringClusterDownOrCloseParams * _Null dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -11189,8 +11060,8 @@ - (void)stopMotionWithParams:(MTRWindowCoveringClusterStopMotionParams * _Nullab // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:baseDevice @@ -11202,12 +11073,11 @@ - (void)stopMotionWithParams:(MTRWindowCoveringClusterStopMotionParams * _Nullab dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -11225,8 +11095,8 @@ - (void)goToLiftValueWithParams:(MTRWindowCoveringClusterGoToLiftValueParams *)p // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:baseDevice @@ -11238,12 +11108,11 @@ - (void)goToLiftValueWithParams:(MTRWindowCoveringClusterGoToLiftValueParams *)p dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -11261,8 +11130,8 @@ - (void)goToLiftPercentageWithParams:(MTRWindowCoveringClusterGoToLiftPercentage // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:baseDevice @@ -11274,12 +11143,11 @@ - (void)goToLiftPercentageWithParams:(MTRWindowCoveringClusterGoToLiftPercentage dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -11297,8 +11165,8 @@ - (void)goToTiltValueWithParams:(MTRWindowCoveringClusterGoToTiltValueParams *)p // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:baseDevice @@ -11310,12 +11178,11 @@ - (void)goToTiltValueWithParams:(MTRWindowCoveringClusterGoToTiltValueParams *)p dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -11333,8 +11200,8 @@ - (void)goToTiltPercentageWithParams:(MTRWindowCoveringClusterGoToTiltPercentage // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:baseDevice @@ -11346,12 +11213,11 @@ - (void)goToTiltPercentageWithParams:(MTRWindowCoveringClusterGoToTiltPercentage dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -11592,8 +11458,8 @@ - (void)barrierControlGoToPercentWithParams:(MTRBarrierControlClusterBarrierCont // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:baseDevice @@ -11605,12 +11471,11 @@ - (void)barrierControlGoToPercentWithParams:(MTRBarrierControlClusterBarrierCont dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -11632,8 +11497,8 @@ - (void)barrierControlStopWithParams:(MTRBarrierControlClusterBarrierControlStop // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:baseDevice @@ -11645,12 +11510,11 @@ - (void)barrierControlStopWithParams:(MTRBarrierControlClusterBarrierControlStop dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -12067,8 +11931,8 @@ - (void)setpointRaiseLowerWithParams:(MTRThermostatClusterSetpointRaiseLowerPara // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:baseDevice @@ -12080,12 +11944,11 @@ - (void)setpointRaiseLowerWithParams:(MTRThermostatClusterSetpointRaiseLowerPara dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -12103,8 +11966,8 @@ - (void)setWeeklyScheduleWithParams:(MTRThermostatClusterSetWeeklyScheduleParams // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:baseDevice @@ -12116,12 +11979,11 @@ - (void)setWeeklyScheduleWithParams:(MTRThermostatClusterSetWeeklyScheduleParams dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -12139,8 +12001,8 @@ - (void)getWeeklyScheduleWithParams:(MTRThermostatClusterGetWeeklyScheduleParams // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:baseDevice @@ -12152,12 +12014,11 @@ - (void)getWeeklyScheduleWithParams:(MTRThermostatClusterGetWeeklyScheduleParams dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -12179,8 +12040,8 @@ - (void)clearWeeklyScheduleWithParams:(MTRThermostatClusterClearWeeklySchedulePa // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:baseDevice @@ -12192,12 +12053,11 @@ - (void)clearWeeklyScheduleWithParams:(MTRThermostatClusterClearWeeklySchedulePa dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -12839,8 +12699,8 @@ - (void)stepWithParams:(MTRFanControlClusterStepParams *)params expectedValues:( // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:baseDevice @@ -12852,12 +12712,11 @@ - (void)stepWithParams:(MTRFanControlClusterStepParams *)params expectedValues:( dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -13170,8 +13029,8 @@ - (void)moveToHueWithParams:(MTRColorControlClusterMoveToHueParams *)params expe // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:baseDevice @@ -13183,12 +13042,11 @@ - (void)moveToHueWithParams:(MTRColorControlClusterMoveToHueParams *)params expe dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -13206,8 +13064,8 @@ - (void)moveHueWithParams:(MTRColorControlClusterMoveHueParams *)params expected // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:baseDevice @@ -13219,12 +13077,11 @@ - (void)moveHueWithParams:(MTRColorControlClusterMoveHueParams *)params expected dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -13242,8 +13099,8 @@ - (void)stepHueWithParams:(MTRColorControlClusterStepHueParams *)params expected // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:baseDevice @@ -13255,12 +13112,11 @@ - (void)stepHueWithParams:(MTRColorControlClusterStepHueParams *)params expected dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -13278,8 +13134,8 @@ - (void)moveToSaturationWithParams:(MTRColorControlClusterMoveToSaturationParams // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:baseDevice @@ -13291,12 +13147,11 @@ - (void)moveToSaturationWithParams:(MTRColorControlClusterMoveToSaturationParams dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -13314,8 +13169,8 @@ - (void)moveSaturationWithParams:(MTRColorControlClusterMoveSaturationParams *)p // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:baseDevice @@ -13327,12 +13182,11 @@ - (void)moveSaturationWithParams:(MTRColorControlClusterMoveSaturationParams *)p dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -13350,8 +13204,8 @@ - (void)stepSaturationWithParams:(MTRColorControlClusterStepSaturationParams *)p // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:baseDevice @@ -13363,12 +13217,11 @@ - (void)stepSaturationWithParams:(MTRColorControlClusterStepSaturationParams *)p dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -13386,8 +13239,8 @@ - (void)moveToHueAndSaturationWithParams:(MTRColorControlClusterMoveToHueAndSatu // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:baseDevice @@ -13399,12 +13252,11 @@ - (void)moveToHueAndSaturationWithParams:(MTRColorControlClusterMoveToHueAndSatu dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -13422,8 +13274,8 @@ - (void)moveToColorWithParams:(MTRColorControlClusterMoveToColorParams *)params // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:baseDevice @@ -13435,12 +13287,11 @@ - (void)moveToColorWithParams:(MTRColorControlClusterMoveToColorParams *)params dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -13458,8 +13309,8 @@ - (void)moveColorWithParams:(MTRColorControlClusterMoveColorParams *)params expe // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:baseDevice @@ -13471,12 +13322,11 @@ - (void)moveColorWithParams:(MTRColorControlClusterMoveColorParams *)params expe dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -13494,8 +13344,8 @@ - (void)stepColorWithParams:(MTRColorControlClusterStepColorParams *)params expe // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:baseDevice @@ -13507,12 +13357,11 @@ - (void)stepColorWithParams:(MTRColorControlClusterStepColorParams *)params expe dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -13530,8 +13379,8 @@ - (void)moveToColorTemperatureWithParams:(MTRColorControlClusterMoveToColorTempe // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:baseDevice @@ -13543,12 +13392,11 @@ - (void)moveToColorTemperatureWithParams:(MTRColorControlClusterMoveToColorTempe dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -13566,8 +13414,8 @@ - (void)enhancedMoveToHueWithParams:(MTRColorControlClusterEnhancedMoveToHuePara // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:baseDevice @@ -13579,12 +13427,11 @@ - (void)enhancedMoveToHueWithParams:(MTRColorControlClusterEnhancedMoveToHuePara dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -13602,8 +13449,8 @@ - (void)enhancedMoveHueWithParams:(MTRColorControlClusterEnhancedMoveHueParams * // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:baseDevice @@ -13615,12 +13462,11 @@ - (void)enhancedMoveHueWithParams:(MTRColorControlClusterEnhancedMoveHueParams * dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -13638,8 +13484,8 @@ - (void)enhancedStepHueWithParams:(MTRColorControlClusterEnhancedStepHueParams * // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:baseDevice @@ -13651,12 +13497,11 @@ - (void)enhancedStepHueWithParams:(MTRColorControlClusterEnhancedStepHueParams * dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -13674,8 +13519,8 @@ - (void)enhancedMoveToHueAndSaturationWithParams:(MTRColorControlClusterEnhanced // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:baseDevice @@ -13687,12 +13532,11 @@ - (void)enhancedMoveToHueAndSaturationWithParams:(MTRColorControlClusterEnhanced dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -13710,8 +13554,8 @@ - (void)colorLoopSetWithParams:(MTRColorControlClusterColorLoopSetParams *)param // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:baseDevice @@ -13723,12 +13567,11 @@ - (void)colorLoopSetWithParams:(MTRColorControlClusterColorLoopSetParams *)param dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -13746,8 +13589,8 @@ - (void)stopMoveStepWithParams:(MTRColorControlClusterStopMoveStepParams *)param // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:baseDevice @@ -13759,12 +13602,11 @@ - (void)stopMoveStepWithParams:(MTRColorControlClusterStopMoveStepParams *)param dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -13782,8 +13624,8 @@ - (void)moveColorTemperatureWithParams:(MTRColorControlClusterMoveColorTemperatu // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:baseDevice @@ -13795,12 +13637,11 @@ - (void)moveColorTemperatureWithParams:(MTRColorControlClusterMoveColorTemperatu dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -13818,8 +13659,8 @@ - (void)stepColorTemperatureWithParams:(MTRColorControlClusterStepColorTemperatu // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:baseDevice @@ -13831,12 +13672,11 @@ - (void)stepColorTemperatureWithParams:(MTRColorControlClusterStepColorTemperatu dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -16381,8 +16221,8 @@ - (void)changeChannelWithParams:(MTRChannelClusterChangeChannelParams *)params e // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:baseDevice @@ -16394,12 +16234,11 @@ - (void)changeChannelWithParams:(MTRChannelClusterChangeChannelParams *)params e dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -16417,8 +16256,8 @@ - (void)changeChannelByNumberWithParams:(MTRChannelClusterChangeChannelByNumberP // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:baseDevice @@ -16430,12 +16269,11 @@ - (void)changeChannelByNumberWithParams:(MTRChannelClusterChangeChannelByNumberP dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -16453,8 +16291,8 @@ - (void)skipChannelWithParams:(MTRChannelClusterSkipChannelParams *)params expec // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:baseDevice @@ -16466,12 +16304,11 @@ - (void)skipChannelWithParams:(MTRChannelClusterSkipChannelParams *)params expec dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -16577,8 +16414,8 @@ - (void)navigateTargetWithParams:(MTRTargetNavigatorClusterNavigateTargetParams // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterTargetNavigator alloc] initWithDevice:baseDevice @@ -16590,12 +16427,11 @@ - (void)navigateTargetWithParams:(MTRTargetNavigatorClusterNavigateTargetParams dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -16690,8 +16526,8 @@ - (void)playWithParams:(MTRMediaPlaybackClusterPlayParams * _Nullable)params exp // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:baseDevice @@ -16703,12 +16539,11 @@ - (void)playWithParams:(MTRMediaPlaybackClusterPlayParams * _Nullable)params exp dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -16730,8 +16565,8 @@ - (void)pauseWithParams:(MTRMediaPlaybackClusterPauseParams * _Nullable)params e // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:baseDevice @@ -16743,12 +16578,11 @@ - (void)pauseWithParams:(MTRMediaPlaybackClusterPauseParams * _Nullable)params e dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -16770,8 +16604,8 @@ - (void)stopWithParams:(MTRMediaPlaybackClusterStopParams * _Nullable)params exp // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:baseDevice @@ -16783,12 +16617,11 @@ - (void)stopWithParams:(MTRMediaPlaybackClusterStopParams * _Nullable)params exp dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -16810,8 +16643,8 @@ - (void)startOverWithParams:(MTRMediaPlaybackClusterStartOverParams * _Nullable) // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:baseDevice @@ -16823,12 +16656,11 @@ - (void)startOverWithParams:(MTRMediaPlaybackClusterStartOverParams * _Nullable) dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -16850,8 +16682,8 @@ - (void)previousWithParams:(MTRMediaPlaybackClusterPreviousParams * _Nullable)pa // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:baseDevice @@ -16863,12 +16695,11 @@ - (void)previousWithParams:(MTRMediaPlaybackClusterPreviousParams * _Nullable)pa dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -16890,8 +16721,8 @@ - (void)nextWithParams:(MTRMediaPlaybackClusterNextParams * _Nullable)params exp // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:baseDevice @@ -16903,12 +16734,11 @@ - (void)nextWithParams:(MTRMediaPlaybackClusterNextParams * _Nullable)params exp dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -16930,8 +16760,8 @@ - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:baseDevice @@ -16943,12 +16773,11 @@ - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -16970,8 +16799,8 @@ - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nulla // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:baseDevice @@ -16983,12 +16812,11 @@ - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nulla dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -17006,8 +16834,8 @@ - (void)skipForwardWithParams:(MTRMediaPlaybackClusterSkipForwardParams *)params // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:baseDevice @@ -17019,12 +16847,11 @@ - (void)skipForwardWithParams:(MTRMediaPlaybackClusterSkipForwardParams *)params dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -17042,8 +16869,8 @@ - (void)skipBackwardWithParams:(MTRMediaPlaybackClusterSkipBackwardParams *)para // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:baseDevice @@ -17055,12 +16882,11 @@ - (void)skipBackwardWithParams:(MTRMediaPlaybackClusterSkipBackwardParams *)para dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -17078,8 +16904,8 @@ - (void)seekWithParams:(MTRMediaPlaybackClusterSeekParams *)params expectedValue // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:baseDevice @@ -17091,12 +16917,11 @@ - (void)seekWithParams:(MTRMediaPlaybackClusterSeekParams *)params expectedValue dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -17324,8 +17149,8 @@ - (void)selectInputWithParams:(MTRMediaInputClusterSelectInputParams *)params ex // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:baseDevice @@ -17337,12 +17162,11 @@ - (void)selectInputWithParams:(MTRMediaInputClusterSelectInputParams *)params ex dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -17364,8 +17188,8 @@ - (void)showInputStatusWithParams:(MTRMediaInputClusterShowInputStatusParams * _ // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:baseDevice @@ -17377,12 +17201,11 @@ - (void)showInputStatusWithParams:(MTRMediaInputClusterShowInputStatusParams * _ dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -17404,8 +17227,8 @@ - (void)hideInputStatusWithParams:(MTRMediaInputClusterHideInputStatusParams * _ // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:baseDevice @@ -17417,12 +17240,11 @@ - (void)hideInputStatusWithParams:(MTRMediaInputClusterHideInputStatusParams * _ dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -17440,8 +17262,8 @@ - (void)renameInputWithParams:(MTRMediaInputClusterRenameInputParams *)params ex // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:baseDevice @@ -17453,12 +17275,11 @@ - (void)renameInputWithParams:(MTRMediaInputClusterRenameInputParams *)params ex dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -17573,8 +17394,8 @@ - (void)sleepWithParams:(MTRLowPowerClusterSleepParams * _Nullable)params expect // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterLowPower alloc] initWithDevice:baseDevice @@ -17586,12 +17407,11 @@ - (void)sleepWithParams:(MTRLowPowerClusterSleepParams * _Nullable)params expect dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -17673,8 +17493,8 @@ - (void)sendKeyWithParams:(MTRKeypadInputClusterSendKeyParams *)params expectedV // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterKeypadInput alloc] initWithDevice:baseDevice @@ -17686,12 +17506,11 @@ - (void)sendKeyWithParams:(MTRKeypadInputClusterSendKeyParams *)params expectedV dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -17772,8 +17591,8 @@ - (void)launchContentWithParams:(MTRContentLauncherClusterLaunchContentParams *) // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:baseDevice @@ -17785,12 +17604,11 @@ - (void)launchContentWithParams:(MTRContentLauncherClusterLaunchContentParams *) dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -17808,8 +17626,8 @@ - (void)launchURLWithParams:(MTRContentLauncherClusterLaunchURLParams *)params e // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:baseDevice @@ -17821,12 +17639,11 @@ - (void)launchURLWithParams:(MTRContentLauncherClusterLaunchURLParams *)params e dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -17936,8 +17753,8 @@ - (void)selectOutputWithParams:(MTRAudioOutputClusterSelectOutputParams *)params // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:baseDevice @@ -17949,12 +17766,11 @@ - (void)selectOutputWithParams:(MTRAudioOutputClusterSelectOutputParams *)params dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -17972,8 +17788,8 @@ - (void)renameOutputWithParams:(MTRAudioOutputClusterRenameOutputParams *)params // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:baseDevice @@ -17985,12 +17801,11 @@ - (void)renameOutputWithParams:(MTRAudioOutputClusterRenameOutputParams *)params dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -18083,8 +17898,8 @@ - (void)launchAppWithParams:(MTRApplicationLauncherClusterLaunchAppParams * _Nul // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:baseDevice @@ -18096,12 +17911,11 @@ - (void)launchAppWithParams:(MTRApplicationLauncherClusterLaunchAppParams * _Nul dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -18119,8 +17933,8 @@ - (void)stopAppWithParams:(MTRApplicationLauncherClusterStopAppParams * _Nullabl // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:baseDevice @@ -18132,12 +17946,11 @@ - (void)stopAppWithParams:(MTRApplicationLauncherClusterStopAppParams * _Nullabl dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -18155,8 +17968,8 @@ - (void)hideAppWithParams:(MTRApplicationLauncherClusterHideAppParams * _Nullabl // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:baseDevice @@ -18168,12 +17981,11 @@ - (void)hideAppWithParams:(MTRApplicationLauncherClusterHideAppParams * _Nullabl dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -18386,8 +18198,8 @@ - (void)getSetupPINWithParams:(MTRAccountLoginClusterGetSetupPINParams *)params // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterAccountLogin alloc] initWithDevice:baseDevice @@ -18399,12 +18211,11 @@ - (void)getSetupPINWithParams:(MTRAccountLoginClusterGetSetupPINParams *)params dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -18422,8 +18233,8 @@ - (void)loginWithParams:(MTRAccountLoginClusterLoginParams *)params expectedValu // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterAccountLogin alloc] initWithDevice:baseDevice @@ -18435,12 +18246,11 @@ - (void)loginWithParams:(MTRAccountLoginClusterLoginParams *)params expectedValu dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -18462,8 +18272,8 @@ - (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterAccountLogin alloc] initWithDevice:baseDevice @@ -18475,12 +18285,11 @@ - (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -18579,8 +18388,8 @@ - (void)getProfileInfoCommandWithParams:(MTRElectricalMeasurementClusterGetProfi // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:baseDevice @@ -18592,12 +18401,11 @@ - (void)getProfileInfoCommandWithParams:(MTRElectricalMeasurementClusterGetProfi dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -18615,8 +18423,8 @@ - (void)getMeasurementProfileCommandWithParams:(MTRElectricalMeasurementClusterG // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:baseDevice @@ -18628,12 +18436,11 @@ - (void)getMeasurementProfileCommandWithParams:(MTRElectricalMeasurementClusterG dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -19452,8 +19259,8 @@ - (void)testWithParams:(MTRUnitTestingClusterTestParams * _Nullable)params expec // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -19465,12 +19272,11 @@ - (void)testWithParams:(MTRUnitTestingClusterTestParams * _Nullable)params expec dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -19492,8 +19298,8 @@ - (void)testNotHandledWithParams:(MTRUnitTestingClusterTestNotHandledParams * _N // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -19505,12 +19311,11 @@ - (void)testNotHandledWithParams:(MTRUnitTestingClusterTestNotHandledParams * _N dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -19532,8 +19337,8 @@ - (void)testSpecificWithParams:(MTRUnitTestingClusterTestSpecificParams * _Nulla // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -19545,12 +19350,11 @@ - (void)testSpecificWithParams:(MTRUnitTestingClusterTestSpecificParams * _Nulla dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -19572,8 +19376,8 @@ - (void)testUnknownCommandWithParams:(MTRUnitTestingClusterTestUnknownCommandPar // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -19585,12 +19389,11 @@ - (void)testUnknownCommandWithParams:(MTRUnitTestingClusterTestUnknownCommandPar dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -19608,8 +19411,8 @@ - (void)testAddArgumentsWithParams:(MTRUnitTestingClusterTestAddArgumentsParams // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -19621,12 +19424,11 @@ - (void)testAddArgumentsWithParams:(MTRUnitTestingClusterTestAddArgumentsParams dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -19644,8 +19446,8 @@ - (void)testSimpleArgumentRequestWithParams:(MTRUnitTestingClusterTestSimpleArgu // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -19657,12 +19459,11 @@ - (void)testSimpleArgumentRequestWithParams:(MTRUnitTestingClusterTestSimpleArgu dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -19680,8 +19481,8 @@ - (void)testStructArrayArgumentRequestWithParams:(MTRUnitTestingClusterTestStruc // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -19693,12 +19494,11 @@ - (void)testStructArrayArgumentRequestWithParams:(MTRUnitTestingClusterTestStruc dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -19716,8 +19516,8 @@ - (void)testStructArgumentRequestWithParams:(MTRUnitTestingClusterTestStructArgu // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -19729,12 +19529,11 @@ - (void)testStructArgumentRequestWithParams:(MTRUnitTestingClusterTestStructArgu dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -19752,8 +19551,8 @@ - (void)testNestedStructArgumentRequestWithParams:(MTRUnitTestingClusterTestNest // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -19765,12 +19564,11 @@ - (void)testNestedStructArgumentRequestWithParams:(MTRUnitTestingClusterTestNest dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -19788,8 +19586,8 @@ - (void)testListStructArgumentRequestWithParams:(MTRUnitTestingClusterTestListSt // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -19801,12 +19599,11 @@ - (void)testListStructArgumentRequestWithParams:(MTRUnitTestingClusterTestListSt dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -19824,8 +19621,8 @@ - (void)testListInt8UArgumentRequestWithParams:(MTRUnitTestingClusterTestListInt // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -19837,12 +19634,11 @@ - (void)testListInt8UArgumentRequestWithParams:(MTRUnitTestingClusterTestListInt dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -19860,8 +19656,8 @@ - (void)testNestedStructListArgumentRequestWithParams:(MTRUnitTestingClusterTest // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -19873,12 +19669,11 @@ - (void)testNestedStructListArgumentRequestWithParams:(MTRUnitTestingClusterTest dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -19896,8 +19691,8 @@ - (void)testListNestedStructListArgumentRequestWithParams:(MTRUnitTestingCluster // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -19909,12 +19704,11 @@ - (void)testListNestedStructListArgumentRequestWithParams:(MTRUnitTestingCluster dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -19932,8 +19726,8 @@ - (void)testListInt8UReverseRequestWithParams:(MTRUnitTestingClusterTestListInt8 // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -19945,12 +19739,11 @@ - (void)testListInt8UReverseRequestWithParams:(MTRUnitTestingClusterTestListInt8 dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -19968,8 +19761,8 @@ - (void)testEnumsRequestWithParams:(MTRUnitTestingClusterTestEnumsRequestParams // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -19981,12 +19774,11 @@ - (void)testEnumsRequestWithParams:(MTRUnitTestingClusterTestEnumsRequestParams dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -20004,8 +19796,8 @@ - (void)testNullableOptionalRequestWithParams:(MTRUnitTestingClusterTestNullable // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -20017,12 +19809,11 @@ - (void)testNullableOptionalRequestWithParams:(MTRUnitTestingClusterTestNullable dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -20040,8 +19831,8 @@ - (void)testComplexNullableOptionalRequestWithParams:(MTRUnitTestingClusterTestC // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -20053,12 +19844,11 @@ - (void)testComplexNullableOptionalRequestWithParams:(MTRUnitTestingClusterTestC dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -20076,8 +19866,8 @@ - (void)simpleStructEchoRequestWithParams:(MTRUnitTestingClusterSimpleStructEcho // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -20089,12 +19879,11 @@ - (void)simpleStructEchoRequestWithParams:(MTRUnitTestingClusterSimpleStructEcho dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -20116,8 +19905,8 @@ - (void)timedInvokeRequestWithParams:(MTRUnitTestingClusterTimedInvokeRequestPar // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -20129,12 +19918,11 @@ - (void)timedInvokeRequestWithParams:(MTRUnitTestingClusterTimedInvokeRequestPar dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -20152,8 +19940,8 @@ - (void)testSimpleOptionalArgumentRequestWithParams:(MTRUnitTestingClusterTestSi // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -20165,12 +19953,11 @@ - (void)testSimpleOptionalArgumentRequestWithParams:(MTRUnitTestingClusterTestSi dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -20188,8 +19975,8 @@ - (void)testEmitTestEventRequestWithParams:(MTRUnitTestingClusterTestEmitTestEve // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -20201,12 +19988,11 @@ - (void)testEmitTestEventRequestWithParams:(MTRUnitTestingClusterTestEmitTestEve dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -20224,8 +20010,8 @@ - (void)testEmitTestFabricScopedEventRequestWithParams:(MTRUnitTestingClusterTes // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:baseDevice @@ -20237,12 +20023,11 @@ - (void)testEmitTestFabricScopedEventRequestWithParams:(MTRUnitTestingClusterTes dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -21814,8 +21599,8 @@ - (void)pingWithParams:(MTRSampleMEIClusterPingParams * _Nullable)params expecte // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterSampleMEI alloc] initWithDevice:baseDevice @@ -21827,12 +21612,11 @@ - (void)pingWithParams:(MTRSampleMEIClusterPingParams * _Nullable)params expecte dispatch_async(self.callbackQueue, ^{ completion(error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; @@ -21850,8 +21634,8 @@ - (void)addArgumentsWithParams:(MTRSampleMEIClusterAddArgumentsParams *)params e // Make a copy of params before we go async. params = [params copy]; MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.device.queue]; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) { - MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue); + workItem.readyHandler = ^(MTRDevice * device, NSInteger retryCount, MTRAsyncWorkCompletionBlock workCompletion) { + MTRClustersLogDequeue(logPrefix, self.device.asyncWorkQueue); auto * baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController]; auto * cluster = [[MTRBaseClusterSampleMEI alloc] initWithDevice:baseDevice @@ -21863,12 +21647,11 @@ - (void)addArgumentsWithParams:(MTRSampleMEIClusterAddArgumentsParams *)params e dispatch_async(self.callbackQueue, ^{ completion(value, error); }); - [workItem endWork]; + workCompletion(MTRAsyncWorkComplete); }]; }; - workItem.readyHandler = readyHandler; - MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue); - [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem]; + MTRClustersLogEnqueue(logPrefix, self.device.asyncWorkQueue); + [self.device.asyncWorkQueue enqueueWorkItem:workItem]; if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) { expectedValues = nil; diff --git a/src/darwin/Framework/CHIPTests/MTRAsyncWorkQueueTests.m b/src/darwin/Framework/CHIPTests/MTRAsyncWorkQueueTests.m index 4fbb1c44468652..d7154afe996d77 100644 --- a/src/darwin/Framework/CHIPTests/MTRAsyncWorkQueueTests.m +++ b/src/darwin/Framework/CHIPTests/MTRAsyncWorkQueueTests.m @@ -15,33 +15,40 @@ */ #import - -// system dependencies #import -#import "MTRAsyncWorkQueue_Internal.h" +#import "MTRAsyncWorkQueue.h" @interface MTRAsyncWorkQueueTests : XCTestCase - @end -@implementation MTRAsyncWorkQueueTests +@implementation MTRAsyncWorkQueueTests { + dispatch_queue_t _backgroundQueue; +} + +- (dispatch_queue_t)backgroundQueue +{ + if (!_backgroundQueue) { + _backgroundQueue = dispatch_queue_create("background queue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + } + return _backgroundQueue; +} - (void)testRunItem { XCTestExpectation * expectation = [self expectationWithDescription:@"Work item called"]; - MTRAsyncWorkQueue * workQueue = [[MTRAsyncWorkQueue alloc] initWithContext:nil queue:dispatch_get_main_queue()]; + id context = [[NSObject alloc] init]; + MTRAsyncWorkQueue * workQueue = [[MTRAsyncWorkQueue alloc] initWithContext:context]; MTRAsyncWorkItem * workItem1 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; __block int counter = 0; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { + workItem1.readyHandler = ^(id handlerContext, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { + XCTAssertIdentical(handlerContext, context); + XCTAssertEqual(retryCount, 0); + XCTAssertTrue(completion(MTRAsyncWorkComplete)); counter++; [expectation fulfill]; - [workItem1 endWork]; - }; - workItem1.readyHandler = readyHandler; - workItem1.cancelHandler = ^{ }; [workQueue enqueueWorkItem:workItem1]; @@ -51,7 +58,7 @@ - (void)testRunItem XCTAssertNil(weakItem); }]; - [self waitForExpectationsWithTimeout:5 handler:nil]; + [self waitForExpectationsWithTimeout:1 handler:nil]; // see that it only ran once XCTAssertEqual(counter, 1); @@ -61,34 +68,28 @@ - (void)testRunItemsSerialized { XCTestExpectation * expectation = [self expectationWithDescription:@"Work item called in order"]; - MTRAsyncWorkQueue * workQueue = [[MTRAsyncWorkQueue alloc] initWithContext:nil queue:dispatch_get_main_queue()]; + MTRAsyncWorkQueue * workQueue = [[MTRAsyncWorkQueue alloc] initWithContext:NSNull.null]; MTRAsyncWorkItem * workItem1 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; __block int counter = 0; - MTRAsyncWorkReadyHandler readyHandler1 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { + workItem1.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { sleep(1); counter++; - [workItem1 endWork]; - }; - workItem1.readyHandler = readyHandler1; - workItem1.cancelHandler = ^{ + completion(MTRAsyncWorkComplete); }; [workQueue enqueueWorkItem:workItem1]; MTRAsyncWorkItem * workItem2 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; - MTRAsyncWorkReadyHandler readyHandler2 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { + workItem2.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { // expect this to have waited until workItem1's sleep(1) finished and incremented counter if (counter == 1) { [expectation fulfill]; } - [workItem2 endWork]; - }; - workItem2.readyHandler = readyHandler2; - workItem2.cancelHandler = ^{ + completion(MTRAsyncWorkComplete); }; [workQueue enqueueWorkItem:workItem2]; - [self waitForExpectationsWithTimeout:5 handler:nil]; + [self waitForExpectationsWithTimeout:2 handler:nil]; // see that workItem1 only ran once XCTAssertEqual(counter, 1); @@ -98,40 +99,34 @@ - (void)testRunItemsRetry { XCTestExpectation * expectation = [self expectationWithDescription:@"Work item called in order"]; - MTRAsyncWorkQueue * workQueue = [[MTRAsyncWorkQueue alloc] initWithContext:nil queue:dispatch_get_main_queue()]; + MTRAsyncWorkQueue * workQueue = [[MTRAsyncWorkQueue alloc] initWithContext:NSNull.null]; MTRAsyncWorkItem * workItem1 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; __block int counter = 0; - MTRAsyncWorkReadyHandler readyHandler1 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { + workItem1.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { sleep(1); counter++; if (retryCount) { // only end after retried once - [workItem1 endWork]; + completion(MTRAsyncWorkComplete); } else { - [workItem1 retryWork]; + completion(MTRAsyncWorkNeedsRetry); } }; - workItem1.readyHandler = readyHandler1; - workItem1.cancelHandler = ^{ - }; [workQueue enqueueWorkItem:workItem1]; MTRAsyncWorkItem * workItem2 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; - MTRAsyncWorkReadyHandler readyHandler2 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { + workItem2.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { // expect this to have waited until workItem1's sleep(1) finished and incremented counter twice if (counter == 2) { [expectation fulfill]; } - [workItem2 endWork]; - }; - workItem2.readyHandler = readyHandler2; - workItem2.cancelHandler = ^{ + completion(MTRAsyncWorkComplete); }; [workQueue enqueueWorkItem:workItem2]; - [self waitForExpectationsWithTimeout:5 handler:nil]; + [self waitForExpectationsWithTimeout:3 handler:nil]; // see that workItem1 ran twice after the retry XCTAssertEqual(counter, 2); @@ -142,57 +137,48 @@ - (void)testRunItemsAfterDrain XCTestExpectation * expectation1 = [self expectationWithDescription:@"First work item caled"]; XCTestExpectation * expectation2 = [self expectationWithDescription:@"Second work item called after drain"]; - MTRAsyncWorkQueue * workQueue = [[MTRAsyncWorkQueue alloc] initWithContext:nil queue:dispatch_get_main_queue()]; + MTRAsyncWorkQueue * workQueue = [[MTRAsyncWorkQueue alloc] initWithContext:NSNull.null]; MTRAsyncWorkItem * workItem1 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; - MTRAsyncWorkReadyHandler readyHandler1 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { - [workItem1 endWork]; + workItem1.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { + completion(MTRAsyncWorkComplete); [expectation1 fulfill]; }; - workItem1.readyHandler = readyHandler1; - workItem1.cancelHandler = ^{ - }; [workQueue enqueueWorkItem:workItem1]; - [self waitForExpectations:@[ expectation1 ] timeout:5]; + [self waitForExpectations:@[ expectation1 ] timeout:2]; MTRAsyncWorkItem * workItem2 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; - MTRAsyncWorkReadyHandler readyHandler2 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { + workItem2.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { [expectation2 fulfill]; - [workItem2 endWork]; - }; - workItem2.readyHandler = readyHandler2; - workItem2.cancelHandler = ^{ + completion(MTRAsyncWorkComplete); }; [workQueue enqueueWorkItem:workItem2]; - [self waitForExpectationsWithTimeout:5 handler:nil]; + [self waitForExpectationsWithTimeout:2 handler:nil]; } - (void)testRunItemNoHandlers { XCTestExpectation * expectation = [self expectationWithDescription:@"Work item called"]; - MTRAsyncWorkQueue * workQueue = [[MTRAsyncWorkQueue alloc] initWithContext:nil queue:dispatch_get_main_queue()]; + MTRAsyncWorkQueue * workQueue = [[MTRAsyncWorkQueue alloc] initWithContext:NSNull.null]; MTRAsyncWorkItem * workItem1 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; MTRAsyncWorkItem * workItem2 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; __block int counter = 0; - MTRAsyncWorkReadyHandler readyHandler = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { + workItem2.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { counter++; - [workItem2 endWork]; + completion(MTRAsyncWorkComplete); [expectation fulfill]; }; - workItem2.readyHandler = readyHandler; - workItem2.cancelHandler = ^{ - }; // Check that trying to run workItem1 does not crash. [workQueue enqueueWorkItem:workItem1]; [workQueue enqueueWorkItem:workItem2]; - [self waitForExpectationsWithTimeout:5 handler:nil]; + [self waitForExpectationsWithTimeout:2 handler:nil]; // see that it only ran once XCTAssertEqual(counter, 1); @@ -203,45 +189,39 @@ - (void)testInvalidation XCTestExpectation * expectation = [self expectationWithDescription:@"Work item called"]; XCTestExpectation * cancelExpectation = [self expectationWithDescription:@"Work item canceled"]; - MTRAsyncWorkQueue * workQueue = [[MTRAsyncWorkQueue alloc] initWithContext:nil queue:dispatch_get_main_queue()]; + MTRAsyncWorkQueue * workQueue = [[MTRAsyncWorkQueue alloc] initWithContext:NSNull.null]; MTRAsyncWorkItem * workItem1 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; - MTRAsyncWorkReadyHandler readyHandler1 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { + workItem1.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { // Give the code enqueing the other items a chance to run, so they can // actually get canceled. sleep(1); [workQueue invalidate]; - [workItem1 endWork]; + XCTAssertFalse(completion(MTRAsyncWorkComplete)); [expectation fulfill]; }; - workItem1.readyHandler = readyHandler1; // No cancel handler on purpose. [workQueue enqueueWorkItem:workItem1]; MTRAsyncWorkItem * workItem2 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; - MTRAsyncWorkReadyHandler readyHandler2 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { - // This should never get called. - XCTAssertFalse(YES); - [workItem2 endWork]; + workItem2.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { + XCTFail("Should not have been called"); + completion(MTRAsyncWorkComplete); }; - workItem2.readyHandler = readyHandler2; - // No cancel handler on purpose. + workItem2.cancelHandler = nil; [workQueue enqueueWorkItem:workItem2]; MTRAsyncWorkItem * workItem3 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; - MTRAsyncWorkReadyHandler readyHandler3 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { - // This should never get called. - XCTAssertFalse(YES); - [workItem3 endWork]; + workItem3.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { + XCTFail("Should not have been called"); + completion(MTRAsyncWorkComplete); }; - dispatch_block_t cancelHandler3 = ^() { + workItem3.cancelHandler = ^{ [cancelExpectation fulfill]; }; - workItem3.readyHandler = readyHandler3; - workItem3.cancelHandler = cancelHandler3; [workQueue enqueueWorkItem:workItem3]; - [self waitForExpectations:@[ expectation, cancelExpectation ] timeout:5]; + [self waitForExpectations:@[ expectation, cancelExpectation ] timeout:2]; } - (void)testBatching @@ -251,18 +231,16 @@ - (void)testBatching __block BOOL workItem2ReadyCalled = NO; XCTestExpectation * workItem3ReadyExpectation = [self expectationWithDescription:@"Work item 3 called"]; - MTRAsyncWorkQueue * workQueue = [[MTRAsyncWorkQueue alloc] initWithContext:nil queue:dispatch_get_main_queue()]; + MTRAsyncWorkQueue * workQueue = [[MTRAsyncWorkQueue alloc] initWithContext:@42]; - // Have a work item sleep so the testing items can queue MTRAsyncWorkItem * workItem0 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; - MTRAsyncWorkReadyHandler readyHandler0 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { + workItem0.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { // While processing item 0, enqueue additional items to test batching MTRAsyncWorkItem * workItem1 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; - MTRAsyncWorkReadyHandler readyHandler1 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { + [workItem1 setReadyHandler:^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { [workItem1ReadyExpectation fulfill]; - [workItem1 endWork]; - }; - workItem1.readyHandler = readyHandler1; + completion(MTRAsyncWorkComplete); + }]; [workItem1 setBatchingID:1 data:@(1) handler:^(id _Nonnull opaqueDataFirst, id _Nonnull opaqueDataSecond, BOOL * _Nonnull fullyMerged) { @@ -270,38 +248,32 @@ - (void)testBatching XCTAssertEqualObjects(opaqueDataSecond, @(2)); *fullyMerged = YES; }]; - // No cancel handler on purpose. [workQueue enqueueWorkItem:workItem1]; MTRAsyncWorkItem * workItem2 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; - MTRAsyncWorkReadyHandler readyHandler2 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { + [workItem2 setReadyHandler:^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { workItem2ReadyCalled = YES; - [workItem2 endWork]; - }; - workItem2.readyHandler = readyHandler2; + completion(MTRAsyncWorkComplete); + }]; [workItem2 setBatchingID:1 data:@(2) handler:^(id _Nonnull opaqueDataFirst, id _Nonnull opaqueDataSecond, BOOL * _Nonnull fullyMerged) { workItem2BatchingCalled = YES; }]; - // No cancel handler on purpose. [workQueue enqueueWorkItem:workItem2]; MTRAsyncWorkItem * workItem3 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; - MTRAsyncWorkReadyHandler readyHandler3 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { + [workItem3 setReadyHandler:^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { [workItem3ReadyExpectation fulfill]; - [workItem3 endWork]; - }; - workItem3.readyHandler = readyHandler3; + completion(MTRAsyncWorkComplete); + }]; [workQueue enqueueWorkItem:workItem3]; - [workItem0 endWork]; + completion(MTRAsyncWorkComplete); }; - workItem0.readyHandler = readyHandler0; - // No cancel handler on purpose. [workQueue enqueueWorkItem:workItem0]; - [self waitForExpectations:@[ workItem1ReadyExpectation, workItem3ReadyExpectation ] timeout:5]; + [self waitForExpectations:@[ workItem1ReadyExpectation, workItem3ReadyExpectation ] timeout:3]; XCTAssertFalse(workItem2BatchingCalled); XCTAssertFalse(workItem2ReadyCalled); @@ -312,17 +284,15 @@ - (void)testDuplicate XCTestExpectation * workItem0ReadyExpectation = [self expectationWithDescription:@"Work item 0 called"]; XCTestExpectation * workItem6ReadyExpectation = [self expectationWithDescription:@"Work item 6 called"]; - MTRAsyncWorkQueue * workQueue = [[MTRAsyncWorkQueue alloc] initWithContext:nil queue:dispatch_get_main_queue()]; + MTRAsyncWorkQueue * workQueue = [[MTRAsyncWorkQueue alloc] initWithContext:NSNull.null]; - // Have a work item sleep so the testing items can queue MTRAsyncWorkItem * workItem0 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; - MTRAsyncWorkReadyHandler readyHandler0 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { + workItem0.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { // While processing item 0, enqueue additional items to test duplicate checking MTRAsyncWorkItem * workItem1 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; - MTRAsyncWorkReadyHandler readyHandler1 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { - [workItem1 endWork]; + workItem1.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { + completion(MTRAsyncWorkComplete); }; - workItem1.readyHandler = readyHandler1; [workItem1 setDuplicateTypeID:1 handler:^(id _Nonnull opaqueItemData, BOOL * _Nonnull isDuplicate, BOOL * stop) { if ([opaqueItemData isEqual:@(1)]) { @@ -335,10 +305,9 @@ - (void)testDuplicate [workQueue enqueueWorkItem:workItem1]; MTRAsyncWorkItem * workItem2 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; - MTRAsyncWorkReadyHandler readyHandler2 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { - [workItem2 endWork]; + workItem2.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { + completion(MTRAsyncWorkComplete); }; - workItem2.readyHandler = readyHandler2; [workItem2 setDuplicateTypeID:1 handler:^(id _Nonnull opaqueItemData, BOOL * _Nonnull isDuplicate, BOOL * stop) { if ([opaqueItemData isEqual:@(2)]) { @@ -351,10 +320,9 @@ - (void)testDuplicate [workQueue enqueueWorkItem:workItem2]; MTRAsyncWorkItem * workItem3 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; - MTRAsyncWorkReadyHandler readyHandler3 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { - [workItem3 endWork]; + workItem3.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { + completion(MTRAsyncWorkComplete); }; - workItem3.readyHandler = readyHandler3; [workItem3 setDuplicateTypeID:2 handler:^(id _Nonnull opaqueItemData, BOOL * _Nonnull isDuplicate, BOOL * stop) { if ([opaqueItemData isEqual:@(1)]) { @@ -367,24 +335,23 @@ - (void)testDuplicate [workQueue enqueueWorkItem:workItem3]; // At this point we should have duplicate type 1 with data @(1) and @(2), and type 2 with data @(1). - XCTAssertTrue([workQueue isDuplicateForTypeID:1 workItemData:@(1)]); - XCTAssertTrue([workQueue isDuplicateForTypeID:1 workItemData:@(2)]); - XCTAssertTrue([workQueue isDuplicateForTypeID:2 workItemData:@(1)]); + XCTAssertTrue([workQueue hasDuplicateForTypeID:1 workItemData:@(1)]); + XCTAssertTrue([workQueue hasDuplicateForTypeID:1 workItemData:@(2)]); + XCTAssertTrue([workQueue hasDuplicateForTypeID:2 workItemData:@(1)]); - XCTAssertFalse([workQueue isDuplicateForTypeID:0 workItemData:@(1)]); - XCTAssertFalse([workQueue isDuplicateForTypeID:0 workItemData:@(2)]); - XCTAssertFalse([workQueue isDuplicateForTypeID:1 workItemData:@(0)]); - XCTAssertFalse([workQueue isDuplicateForTypeID:1 workItemData:@(3)]); - XCTAssertFalse([workQueue isDuplicateForTypeID:2 workItemData:@(2)]); + XCTAssertFalse([workQueue hasDuplicateForTypeID:0 workItemData:@(1)]); + XCTAssertFalse([workQueue hasDuplicateForTypeID:0 workItemData:@(2)]); + XCTAssertFalse([workQueue hasDuplicateForTypeID:1 workItemData:@(0)]); + XCTAssertFalse([workQueue hasDuplicateForTypeID:1 workItemData:@(3)]); + XCTAssertFalse([workQueue hasDuplicateForTypeID:2 workItemData:@(2)]); // Test returning *isDuplicate=NO and queuing one extra duplicate item, and that the extra item runs // First have a regular item with ID/data == 3/1 MTRAsyncWorkItem * workItem4 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; - MTRAsyncWorkReadyHandler readyHandler4 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { - [workItem4 endWork]; + workItem4.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { + completion(MTRAsyncWorkComplete); }; - workItem4.readyHandler = readyHandler4; [workItem4 setDuplicateTypeID:3 handler:^(id _Nonnull opaqueItemData, BOOL * _Nonnull isDuplicate, BOOL * stop) { if ([opaqueItemData isEqual:@(1)]) { @@ -396,14 +363,13 @@ - (void)testDuplicate }]; [workQueue enqueueWorkItem:workItem4]; - XCTAssertTrue([workQueue isDuplicateForTypeID:3 workItemData:@(1)]); + XCTAssertTrue([workQueue hasDuplicateForTypeID:3 workItemData:@(1)]); // Have a barrier item with ID/data == 3/1 that returns *isDuplicate=NO MTRAsyncWorkItem * workItem5 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; - MTRAsyncWorkReadyHandler readyHandler5 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { - [workItem5 endWork]; + workItem5.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { + completion(MTRAsyncWorkComplete); }; - workItem5.readyHandler = readyHandler5; [workItem5 setDuplicateTypeID:3 handler:^(id _Nonnull opaqueItemData, BOOL * _Nonnull isDuplicate, BOOL * stop) { if ([opaqueItemData isEqual:@(1)]) { @@ -416,15 +382,14 @@ - (void)testDuplicate [workQueue enqueueWorkItem:workItem5]; // After the above, the same ID/data should no longer be considered duplicate - XCTAssertFalse([workQueue isDuplicateForTypeID:3 workItemData:@(1)]); + XCTAssertFalse([workQueue hasDuplicateForTypeID:3 workItemData:@(1)]); // Now add regular regular item with ID/data == 3/1 MTRAsyncWorkItem * workItem6 = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; - MTRAsyncWorkReadyHandler readyHandler6 = ^(MTRDevice * _Nonnull device, NSUInteger retryCount) { - [workItem6 endWork]; + workItem6.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { + completion(MTRAsyncWorkComplete); [workItem6ReadyExpectation fulfill]; }; - workItem6.readyHandler = readyHandler6; [workItem6 setDuplicateTypeID:3 handler:^(id _Nonnull opaqueItemData, BOOL * _Nonnull isDuplicate, BOOL * stop) { if ([opaqueItemData isEqual:@(1)]) { @@ -437,15 +402,92 @@ - (void)testDuplicate [workQueue enqueueWorkItem:workItem6]; // After the above, the same ID/data should no longer be considered duplicate - XCTAssertTrue([workQueue isDuplicateForTypeID:3 workItemData:@(1)]); + XCTAssertTrue([workQueue hasDuplicateForTypeID:3 workItemData:@(1)]); - [workItem0 endWork]; + completion(MTRAsyncWorkComplete); [workItem0ReadyExpectation fulfill]; }; - workItem0.readyHandler = readyHandler0; [workQueue enqueueWorkItem:workItem0]; [self waitForExpectations:@[ workItem0ReadyExpectation, workItem6ReadyExpectation ] timeout:5]; } +- (void)testNoRetainCycles +{ + NSPointerArray * objects = [NSPointerArray weakObjectsPointerArray]; + @autoreleasepool { + __block MTRAsyncWorkCompletionBlock workCompletion; + @autoreleasepool { + MTRAsyncWorkQueue * queue = [[MTRAsyncWorkQueue alloc] initWithContext:self]; + [objects addPointer:(__bridge void *) queue]; + MTRAsyncWorkItem * work = [[MTRAsyncWorkItem alloc] initWithQueue:self.backgroundQueue]; + dispatch_semaphore_t workReady = dispatch_semaphore_create(0); + dispatch_semaphore_t readyHandlerDone = dispatch_semaphore_create(0); + work.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { + dispatch_semaphore_wait(workReady, DISPATCH_TIME_FOREVER); + workCompletion = completion; // retain outside inner ARP, simulating ongoing work + dispatch_async(self.backgroundQueue, ^{ + dispatch_semaphore_signal(readyHandlerDone); + }); + }; + [objects addPointer:(__bridge void *) work]; + [queue enqueueWorkItem:work]; + XCTAssertEqual(objects.allObjects.count, 2); + + dispatch_semaphore_signal(workReady); + dispatch_semaphore_wait(readyHandlerDone, DISPATCH_TIME_FOREVER); + // Not calling [queue invalidate] + } + + // We've dropped the work queue but the work item may + // still be retained by the work completion block. + XCTAssertNotNil(workCompletion); + NSArray * retained = objects.allObjects; + if (retained.count > 0) { + XCTAssertEqual(retained.count, 1); + XCTAssert([retained.firstObject isKindOfClass:MTRAsyncWorkItem.class]); + } + workCompletion = nil; + } + + // Everything should be gone now + XCTAssertEqualObjects(objects.allObjects, @[]); +} + +- (void)testContextLoss +{ + // Use a CFTypeRef so we can explicitly control the reference count + CFTypeRef testContext = CFBridgingRetain([[NSObject alloc] init]); + XCTAssertEqual(CFGetRetainCount(testContext), 1, @"internal test error"); + MTRAsyncWorkQueue * queue = [[MTRAsyncWorkQueue alloc] initWithContext:(__bridge id) testContext]; + + dispatch_semaphore_t ready = dispatch_semaphore_create(0); + dispatch_semaphore_t proceed = dispatch_semaphore_create(0); + MTRAsyncWorkItem * setup = [[MTRAsyncWorkItem alloc] initWithQueue:self.backgroundQueue]; + setup.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { + // dispatch again because `context` is retained by the caller + dispatch_async(self.backgroundQueue, ^{ + dispatch_semaphore_signal(ready); + dispatch_semaphore_wait(proceed, DISPATCH_TIME_FOREVER); + completion(MTRAsyncWorkComplete); + }); + }; + [queue enqueueWorkItem:setup]; + + // Enqueue work item. It should not run because we will drop the context first. + XCTestExpectation * workRun = [self expectationWithDescription:@"work ready handler run"]; + workRun.inverted = YES; + MTRAsyncWorkItem * work = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; + work.readyHandler = ^(id context, NSInteger retryCount, MTRAsyncWorkCompletionBlock completion) { + [workRun fulfill]; + }; + [queue enqueueWorkItem:work]; + + dispatch_semaphore_wait(ready, DISPATCH_TIME_FOREVER); + XCTAssertEqual(CFGetRetainCount(testContext), 1, @"internal test error"); + CFRelease(testContext); + dispatch_semaphore_signal(proceed); + [self waitForExpectationsWithTimeout:1 handler:nil]; +} + @end diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index b5a63a11efa6df..5c68dd1d2cba9f 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -122,7 +122,6 @@ 3D843717294979230070D20A /* MTRClusters_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D843715294979230070D20A /* MTRClusters_Internal.h */; }; 3D843756294AD25A0070D20A /* MTRCertificateInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D843754294AD25A0070D20A /* MTRCertificateInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3D843757294AD25A0070D20A /* MTRCertificateInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3D843755294AD25A0070D20A /* MTRCertificateInfo.mm */; }; - 3DA1A3542ABAB3B4004F0BB9 /* MTRAsyncWorkQueue_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DA1A3512ABAB3B4004F0BB9 /* MTRAsyncWorkQueue_Internal.h */; }; 3DA1A3552ABAB3B4004F0BB9 /* MTRAsyncWorkQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DA1A3522ABAB3B4004F0BB9 /* MTRAsyncWorkQueue.h */; }; 3DA1A3562ABAB3B4004F0BB9 /* MTRAsyncWorkQueue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3DA1A3532ABAB3B4004F0BB9 /* MTRAsyncWorkQueue.mm */; }; 3DA1A3582ABABF6A004F0BB9 /* MTRAsyncWorkQueueTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DA1A3572ABABF69004F0BB9 /* MTRAsyncWorkQueueTests.m */; }; @@ -476,7 +475,6 @@ 3D84372F294984AF0070D20A /* command_completion_type.zapt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = command_completion_type.zapt; sourceTree = ""; }; 3D843754294AD25A0070D20A /* MTRCertificateInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRCertificateInfo.h; sourceTree = ""; }; 3D843755294AD25A0070D20A /* MTRCertificateInfo.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRCertificateInfo.mm; sourceTree = ""; }; - 3DA1A3512ABAB3B4004F0BB9 /* MTRAsyncWorkQueue_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRAsyncWorkQueue_Internal.h; sourceTree = ""; }; 3DA1A3522ABAB3B4004F0BB9 /* MTRAsyncWorkQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRAsyncWorkQueue.h; sourceTree = ""; }; 3DA1A3532ABAB3B4004F0BB9 /* MTRAsyncWorkQueue.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRAsyncWorkQueue.mm; sourceTree = ""; }; 3DA1A3572ABABF69004F0BB9 /* MTRAsyncWorkQueueTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTRAsyncWorkQueueTests.m; sourceTree = ""; }; @@ -1100,7 +1098,6 @@ 7596A84628762783004DAE0E /* MTRAsyncCallbackWorkQueue.h */, 7596A84728762783004DAE0E /* MTRAsyncCallbackWorkQueue.mm */, 3DA1A3522ABAB3B4004F0BB9 /* MTRAsyncWorkQueue.h */, - 3DA1A3512ABAB3B4004F0BB9 /* MTRAsyncWorkQueue_Internal.h */, 3DA1A3532ABAB3B4004F0BB9 /* MTRAsyncWorkQueue.mm */, 3CF134AA289D8DF70017A19E /* MTRDeviceAttestationInfo.h */, 3CF134AC289D8E570017A19E /* MTRDeviceAttestationInfo.mm */, @@ -1459,7 +1456,6 @@ 51565CB12A7AD77600469F18 /* MTRDeviceControllerDataStore.h in Headers */, 3D843713294977000070D20A /* NSDataSpanConversion.h in Headers */, 991DC08B247704DC00C13860 /* MTRLogging_Internal.h in Headers */, - 3DA1A3542ABAB3B4004F0BB9 /* MTRAsyncWorkQueue_Internal.h in Headers */, 1E4D655029C208DD00BC3478 /* MTRCommissionableBrowserDelegate.h in Headers */, 7596A84828762783004DAE0E /* MTRAsyncCallbackWorkQueue.h in Headers */, 5A7947E527C0129F00434CF2 /* MTRDeviceController+XPC.h in Headers */,