Skip to content

Commit a7468a4

Browse files
sherginfacebook-github-bot
authored andcommitted
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
1 parent 274f10f commit a7468a4

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

React/Base/RCTUtils.m

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -264,14 +264,29 @@ void RCTUnsafeExecuteOnMainQueueSync(dispatch_block_t block)
264264
}
265265
}
266266

267+
static void RCTUnsafeExecuteOnMainQueueOnceSync(dispatch_once_t *onceToken, dispatch_block_t block)
268+
{
269+
// The solution was borrowed from a post by Ben Alpert:
270+
// https://benalpert.com/2014/04/02/dispatch-once-initialization-on-the-main-thread.html
271+
// See also: https://www.mikeash.com/pyblog/friday-qa-2014-06-06-secrets-of-dispatch_once.html
272+
if (RCTIsMainQueue()) {
273+
dispatch_once(onceToken, block);
274+
} else {
275+
if (DISPATCH_EXPECT(*onceToken == 0L, NO)) {
276+
dispatch_sync(dispatch_get_main_queue(), ^{
277+
dispatch_once(onceToken, block);
278+
});
279+
}
280+
}
281+
}
282+
267283
CGFloat RCTScreenScale()
268284
{
269-
static CGFloat scale;
270285
static dispatch_once_t onceToken;
271-
dispatch_once(&onceToken, ^{
272-
RCTUnsafeExecuteOnMainQueueSync(^{
273-
scale = [UIScreen mainScreen].scale;
274-
});
286+
static CGFloat scale;
287+
288+
RCTUnsafeExecuteOnMainQueueOnceSync(&onceToken, ^{
289+
scale = [UIScreen mainScreen].scale;
275290
});
276291

277292
return scale;

0 commit comments

Comments
 (0)