Skip to content

Commit c8eea02

Browse files
Log the number of work items when adding/removing to MTRAsyncWorkQueue.
We used to have logging for this, but it seems to have gotten lost. Would be useful to know how many work items are in the queue after one is added. Also makes ContextSnapshot assert the relevant lock is not held, and cleans up some manual lock/unlock to use the auto helper.
1 parent 0c0c6d6 commit c8eea02

File tree

1 file changed

+33
-29
lines changed

1 file changed

+33
-29
lines changed

src/darwin/Framework/CHIP/MTRAsyncWorkQueue.mm

+33-29
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,6 @@ typedef NS_ENUM(NSInteger, MTRAsyncWorkItemState) {
3333
MTRAsyncWorkItemRetryCountBase = MTRAsyncWorkItemRunning, // values >= MTRAsyncWorkItemRunning encode retryCount
3434
};
3535

36-
// A helper struct that facilitates access to _context while
37-
// - only reading the _context weak reference once and retaining a strong
38-
// reference for the duration of a particular queue method call
39-
// - avoiding calls to `[context description]` under our lock
40-
struct ContextSnapshot {
41-
id _Nullable reference;
42-
NSString * _Nullable description;
43-
ContextSnapshot(id _Nullable context)
44-
{
45-
reference = context;
46-
description = [context description];
47-
}
48-
};
49-
5036
MTR_DIRECT_MEMBERS
5137
@implementation MTRAsyncWorkItem {
5238
dispatch_queue_t _queue;
@@ -214,6 +200,21 @@ @implementation MTRAsyncWorkQueue {
214200
NSInteger _runningWorkItemCount;
215201
}
216202

203+
// A helper struct that facilitates access to _context while
204+
// - only reading the _context weak reference once and retaining a strong
205+
// reference for the duration of a particular queue method call
206+
// - avoiding calls to `[context description]` under our lock
207+
struct ContextSnapshot {
208+
id _Nullable reference;
209+
NSString * _Nullable description;
210+
ContextSnapshot(MTRAsyncWorkQueue * queue)
211+
{
212+
os_unfair_lock_assert_not_owner(&queue->_lock);
213+
reference = queue->_context;
214+
description = [reference description];
215+
}
216+
};
217+
217218
- (instancetype)initWithContext:(id)context
218219
{
219220
NSParameterAssert(context);
@@ -224,13 +225,18 @@ - (instancetype)initWithContext:(id)context
224225
return self;
225226
}
226227

228+
- (NSString *)_lockedSelfDescription:(const ContextSnapshot &)context
229+
{
230+
os_unfair_lock_assert_owner(&_lock);
231+
232+
return [NSString stringWithFormat:@"%@, items count: %tu", context.description, _items.count];
233+
}
234+
227235
- (NSString *)description
228236
{
229-
NSUInteger itemsCount;
230-
os_unfair_lock_lock(&_lock);
231-
itemsCount = _items.count;
232-
os_unfair_lock_unlock(&_lock);
233-
return [NSString stringWithFormat:@"<%@ context: %@ items count: %tu>", self.class, _context, itemsCount];
237+
ContextSnapshot context(self);
238+
std::lock_guard lock(_lock);
239+
return [NSString stringWithFormat:@"<%@ context: %@>", self.class, [self _lockedSelfDescription:context]];
234240
}
235241

236242
- (void)enqueueWorkItem:(MTRAsyncWorkItem *)item
@@ -251,29 +257,28 @@ - (void)enqueueWorkItem:(MTRAsyncWorkItem *)item
251257
description:(nullable NSString *)description
252258
{
253259
NSParameterAssert(item);
254-
ContextSnapshot context(_context); // outside of lock
260+
ContextSnapshot context(self); // outside of lock
255261
NSAssert(context.reference, @"context has been lost");
256262

257-
os_unfair_lock_lock(&_lock);
263+
std::lock_guard lock(_lock);
258264
[item markEnqueued];
259265
[_items addObject:item];
260266

261267
if (description) {
262268
// Logging the description once is enough because other log messages
263269
// related to the work item (execution, completion etc) can easily be
264270
// correlated using the unique id.
265-
MTR_LOG_DEFAULT("MTRAsyncWorkQueue<%@> enqueued work item [%llu]: %@", context.description, item.uniqueID, description);
271+
MTR_LOG_DEFAULT("MTRAsyncWorkQueue<%@> enqueued work item [%llu]: %@", [self _lockedSelfDescription:context], item.uniqueID, description);
266272
} else {
267-
MTR_LOG_DEFAULT("MTRAsyncWorkQueue<%@> enqueued work item [%llu]", context.description, item.uniqueID);
273+
MTR_LOG_DEFAULT("MTRAsyncWorkQueue<%@> enqueued work item [%llu]", [self _lockedSelfDescription:context], item.uniqueID);
268274
}
269275

270276
[self _callNextReadyWorkItemWithContext:context];
271-
os_unfair_lock_unlock(&_lock);
272277
}
273278

274279
- (void)invalidate
275280
{
276-
ContextSnapshot context(_context); // outside of lock
281+
ContextSnapshot context(self); // outside of lock
277282
std::lock_guard lock(_lock);
278283
MTR_LOG_INFO("MTRAsyncWorkQueue<%@> invalidate %tu items", context.description, _items.count);
279284
for (MTRAsyncWorkItem * item in _items) {
@@ -299,7 +304,7 @@ - (void)_postProcessWorkItem:(MTRAsyncWorkItem *)workItem
299304
} else {
300305
[workItem markComplete];
301306
[_items removeObjectAtIndex:0];
302-
MTR_LOG_DEFAULT("MTRAsyncWorkQueue<%@> completed work item [%llu]", context.description, workItem.uniqueID);
307+
MTR_LOG_DEFAULT("MTRAsyncWorkQueue<%@> completed work item [%llu]", [self _lockedSelfDescription:context], workItem.uniqueID);
303308
}
304309

305310
// when "concurrency width" is implemented this will be decremented instead
@@ -362,13 +367,12 @@ - (void)_callNextReadyWorkItemWithContext:(ContextSnapshot const &)context
362367
mtr_strongify(self);
363368
BOOL handled = NO;
364369
if (self) {
365-
ContextSnapshot context(self->_context); // re-acquire a new snapshot
366-
os_unfair_lock_lock(&self->_lock);
370+
ContextSnapshot context(self); // re-acquire a new snapshot
371+
std::lock_guard lock(self->_lock);
367372
if (!workItem.isComplete) {
368373
[self _postProcessWorkItem:workItem context:context retry:(outcome == MTRAsyncWorkNeedsRetry)];
369374
handled = YES;
370375
}
371-
os_unfair_lock_unlock(&self->_lock);
372376
}
373377
return handled;
374378
}];

0 commit comments

Comments
 (0)