Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.

Commit 64ad48a

Browse files
committed
Merge pull request #1097 from facebook/iOS9ConcurrentImageDecodingSystemBug
[ASImageNode] @synchronized around UIImage draw to prevent concurrently decoding the same instance.
2 parents 2c5db2e + 2648874 commit 64ad48a

1 file changed

Lines changed: 15 additions & 1 deletion

File tree

AsyncDisplayKit/ASImageNode.mm

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,21 @@ + (UIImage *)displayWithParameters:(_ASImageNodeDrawParameters *)parameters isCa
235235
UIRectFill({ .size = backingSize });
236236
}
237237

238-
[image drawInRect:imageDrawRect];
238+
// iOS 9 appears to contain a thread safety regression when drawing the same CGImageRef on
239+
// multiple threads concurrently. In fact, instead of crashing, it appears to deadlock.
240+
// The issue is present in Mac OS X El Capitan and has been seen hanging Pro apps like Adobe Premier,
241+
// as well as iOS games, and a small number of ASDK apps that provide the same image reference
242+
// to many separate ASImageNodes. A workaround is to set .displaysAsynchronously = NO for the nodes
243+
// that may get the same pointer for a given UI asset image, etc.
244+
// FIXME: We should replace @synchronized here, probably using a global, locked NSMutableSet, and
245+
// only if the object already exists in the set we should create a semaphore to signal waiting threads
246+
// upon removal of the object from the set when the operation completes.
247+
// Another option is to have ASDisplayNode+AsyncDisplay coordinate these cases, and share the decoded buffer.
248+
// Details tracked in https://github.com/facebook/AsyncDisplayKit/issues/1068
249+
250+
@synchronized(image) {
251+
[image drawInRect:imageDrawRect];
252+
}
239253

240254
if (isCancelled()) {
241255
UIGraphicsEndImageContext();

0 commit comments

Comments
 (0)