Permalink
Browse files

Introducing smart `RCTUnsafeExecuteOnMainQueueOnceSync()` and fixed `…

…RCTScreenScale()`

Summary:
(This diff was decoupled from D4983054 which landing was quite delayed.)

`RCTUnsafeExecuteOnMainQueueOnceSync()` synchronously executes a block once, on main queue.
I found that our old implementation of `RCTScreenScale()` causes deadlock when it is called from main and background thread simultaneously.
After I implemented my own solution I googled this issue and found an article by Ben Alpert with this awesome helper:
https://benalpert.com/2014/04/02/dispatch-once-initialization-on-the-main-thread.html
So, I found it super useful and borrowed it.

Hey spicyj! :)

Reviewed By: fkgozali

Differential Revision: D5632592

fbshipit-source-id: dff43a5780b7404a3cc109c66c131cef4f4df429
  • Loading branch information...
shergin authored and facebook-github-bot committed Aug 15, 2017
1 parent 274f10f commit a7468a4acfad40f4af459b7d6aecf32c1107dfbe
Showing with 20 additions and 5 deletions.
  1. +20 −5 React/Base/RCTUtils.m
View
@@ -264,14 +264,29 @@ void RCTUnsafeExecuteOnMainQueueSync(dispatch_block_t block)
}
}
static void RCTUnsafeExecuteOnMainQueueOnceSync(dispatch_once_t *onceToken, dispatch_block_t block)
{
// The solution was borrowed from a post by Ben Alpert:
// https://benalpert.com/2014/04/02/dispatch-once-initialization-on-the-main-thread.html
// See also: https://www.mikeash.com/pyblog/friday-qa-2014-06-06-secrets-of-dispatch_once.html
if (RCTIsMainQueue()) {
dispatch_once(onceToken, block);
} else {
if (DISPATCH_EXPECT(*onceToken == 0L, NO)) {
dispatch_sync(dispatch_get_main_queue(), ^{
dispatch_once(onceToken, block);
});
}
}
}
CGFloat RCTScreenScale()
{
static CGFloat scale;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
RCTUnsafeExecuteOnMainQueueSync(^{
scale = [UIScreen mainScreen].scale;
});
static CGFloat scale;
RCTUnsafeExecuteOnMainQueueOnceSync(&onceToken, ^{
scale = [UIScreen mainScreen].scale;
});
return scale;

0 comments on commit a7468a4

Please sign in to comment.