RCTScreenScale may deadlock
See original GitHub issueRCTScreenScale will deadlock if it called for the first time on a non-main thread and the main thread is waiting synchronously for the thread on which RCTScreenScale
is called, because the dispatch_sync(dispatch_get_main_queue(), ...)
in RCTUnsafeExecuteOnMainQueueOnceSync
will deadlock in that scenario. I don’t know whether this can actually happen in a React Native app, but if not it should probably be commented on in the code (e.g. to prevent people from copying the code without taking this issue into account).
Because of this issue, having a general helper function like RCTUnsafeExecuteOnMainQueueOnceSync
is problematic. For use cases like RCTScreenScale
it’s usually better to do the initialization work eagerly at app startup or library load time (e.g. in an Objective-C category load
method).
Apart from this general issue, RCTUnsafeExecuteOnMainQueueOnceSync
also misses a compiler barrier in the second if statement, see the dispatch_once
inline function implementation in more recent libdispatch versions, e.g. https://github.com/apple/swift-corelibs-libdispatch/blob/b5ec5d8dfa59426912fbb4884fab642804b99827/dispatch/once.h#L86
Also, if you copy the internals of dispatch_once
, I’d use exactly the same predicate test against ~0L
instead of 0
, just in case that it may matter for some obscure reason.
Finally, I’d like to point out that RCTScreenScale
currently doesn’t handle the case where the scale of the mainScreen
changes, which I think could happen on the Apple TV.
Issue Analytics
- State:
- Created 6 years ago
- Comments:8 (4 by maintainers)
Top GitHub Comments
@shergin Care to comment? I believe that we never dispatch synchronously from the main thread to this RN thread, precisely to avoid deadlock, but I am not sure.
It’s true that screen size can change and I don’t think our APIs are really set up to accommodate that at the moment. 😦
@shergin Do you think we can close this issue?