Skip to content

RCTScreenScale may deadlock #18096

Closed
Closed
@stephan-tolksdorf

Description

@stephan-tolksdorf

RCTScreenScale 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions