I have received multiple crash reports from various users over the last month related to this same issue (per Crashlytics: BUG IN CLIENT OF LIBDISPATCH: dispatch_sync called on queue already owned by current thread). All devices are running 11.3.1.
I believe what is happening is as described in this pseudocode
dispatch_sync(queueA, ^{
dispatch_sync(queueB, ^{
// dispatch_get_current_queue() is B, but A is blocked,
// so a dispatch_sync(A,b) will deadlock.
dispatch_sync(queueA, ^{
// some task
});
});
});
because if you start at the method line 5 in the stack trace
- (BOOL)endSegmentWithInfo:(NSDictionary *)info completionHandler:(void(^)(SCRecordSessionSegment *segment, NSError* error))completionHandler {
__block BOOL success = NO;
[self dispatchSyncOnSessionQueue:^{
dispatch_sync(_audioQueue, ^{
if (_recordSegmentReady) {
_recordSegmentReady = NO;
success = YES;
AVAssetWriter *writer = _assetWriter;
if (writer != nil) {
BOOL currentSegmentEmpty = (!_currentSegmentHasVideo && !_currentSegmentHasAudio);
if (currentSegmentEmpty) {
[writer cancelWriting];
[self _destroyAssetWriter];
[self removeFile:writer.outputURL];
if (completionHandler != nil) {
dispatch_async(dispatch_get_main_queue(), ^{
completionHandler(nil, nil);
});
}
} else {
// NSLog(@"Ending session at %fs", CMTimeGetSeconds(_currentSegmentDuration));
[writer endSessionAtSourceTime:CMTimeAdd(_currentSegmentDuration, _sessionStartTime)];
[writer finishWritingWithCompletionHandler: ^{
[self appendRecordSegmentUrl:writer.outputURL info:info error:writer.error completionHandler:completionHandler];
}];
}
} else {
[_movieFileOutput stopRecording];
}
} else {
dispatch_async(dispatch_get_main_queue(), ^{
if (completionHandler != nil) {
completionHandler(nil, [SCRecordSession createError:@"The current record segment is not ready for this operation"]);
}
});
}
});
}];
return success;
}
this creates a similar nesting queue structure session queue -> audioQueue -> sessionQueue. I am not strong in this area though so might be going down the wrong path.
I have received multiple crash reports from various users over the last month related to this same issue (per Crashlytics: BUG IN CLIENT OF LIBDISPATCH: dispatch_sync called on queue already owned by current thread). All devices are running 11.3.1.
I believe what is happening is as described in this pseudocode
because if you start at the method line 5 in the stack trace
this creates a similar nesting queue structure session queue -> audioQueue -> sessionQueue. I am not strong in this area though so might be going down the wrong path.