Closed cltnschlosser closed 11 months ago
Hey! 👋
The issue doesn't seem to contain a minimal reproduction.
Could you provide a snippet of code, a snack or a link to a GitHub repository that reproduces the problem?
I have the same issue.
same here
same here
same error w/ pretty similar stack trace, can only see this behaviour on iOS though. "react-native-reanimated": "^2.5.0"
Also seeing this. iPhone7 and iPad mini. I'm still on react-native-reanimated 2.3.3 though.
I can observe this issue using in the latest version (2.8.0) as well.
I'm facing exactly the same one. Did you find a solution for that issue? Really appreciate that. Thank you guys
"@react-navigation/bottom-tabs": "^6.0.9", "@react-navigation/core": "^6.1.0", "@react-navigation/native": "^6.0.6", "@react-navigation/stack": "^6.0.11", "react-native-reanimated": "~2.3.3", "react-native-screens": "^3.13.1"
Same here
"react-native-reanimated": "2.3.1", "@react-navigation/bottom-tabs": "5.11.2", "@react-navigation/native": "~5.8.10", "@react-navigation/stack": "~5.12.8",
Is anyone reviewing cltnschlosser's PR? Or fixing the problem in some other way?
Samesies here! The iOS app works just fine but the android app refuses to change the screen.
"@react-navigation/devtools": "^6.0.7",
"@react-navigation/drawer": "^6.4.1",
"@react-navigation/native": "^6.0.10",
"@react-navigation/native-stack": "^6.6.2",
"react-native-reanimated": "^2.8.0",
"react-native": "0.68.1",
A simple workaround would be required just in the short term for us :-)
Same
anybody here some thoughts on a workaround? I am still stuck and don't know how to resolve the matter as it is the navigation library that causes it. :-/
same
same here
Any update on this?
After merging in this PR locally, we saw a noticeable drop in iOS native app crashes over the last 90 days:
same here
Hey! 👋
The issue doesn't seem to contain a minimal reproduction.
Could you provide a snack or a link to a GitHub repository under your username that reproduces the problem?
same here "react-native-reanimated": "2.9.1", "react-native": "0.64.2",
Same here
App crashes when you go back to foreground And randomly when open the app
"react-native-reanimated": "^2.10.0", "react-native": "0.67.4",
In Pods RNReanimated > ios > REANodesManager > -performOperations
This crash it doesn't even get caught by Crashlytics
Facing same issue on android multiple devices: React-native : 0.66.4 react-native-reanimated : 2.9.1 (^2.2 on package.json)
"@ptomasroos/react-native-multi-slider": "^2.2.2",
"@react-native-async-storage/async-storage": "^1.15.4",
"@react-native-community/art": "https://github.com/react-native-art/art.git",
"@react-native-community/blur": "^3.6.0",
"@react-native-community/masked-view": "^0.1.10",
"@react-native-community/slider": "^3.0.3",
"@react-native-firebase/analytics": "^11.5.0",
"@react-native-firebase/app": "^11.5.0",
"@react-native-firebase/crashlytics": "^11.5.0",
"@react-native-firebase/messaging": "^11.5.0",
"@react-native-firebase/perf": "^11.5.0",
"@react-navigation/bottom-tabs": "^5.11.9",
"@react-navigation/native": "^5.9.4",
"@react-navigation/stack": "^5.14.4",
"@reduxjs/toolkit": "^1.5.1",
"@sentry/react-native": "^3.1.1",
"@shopify/restyle": "^1.4.0",
"@snowplow/react-native-tracker": "^1.2.1",
"axios": "^0.21.1",
"babel-plugin-module-resolver": "^4.1.0",
"babel-plugin-transform-remove-console": "^6.9.4",
"clevertap-react-native": "^0.8.1",
"launchdarkly-react-native-client-sdk": "^5.1.0",
"lodash": "^4.17.21",
"lottie-ios": "3.4.0",
"lottie-react-native": "^5.1.3",
"moment": "^2.29.1",
"query-string": "^7.0.0",
"react": "17.0.2",
"react-native": "0.66.3",
"react-native-branch": "^5.5.0",
"react-native-code-push": "^7.0.4",
"react-native-dash": "^0.0.11",
"react-native-dropdown-picker": "5.0",
"react-native-fast-image": "^8.3.4",
"react-native-fbsdk-next": "^7.0.1",
"react-native-flipper": "^0.91.2",
"react-native-geocoding": "^0.5.0",
"react-native-geolocation-service": "5.2.0",
"react-native-gesture-handler": "^2.4.0",
"react-native-image-pan-zoom": "^2.1.12",
"react-native-in-app-review": "^3.2.3",
"react-native-linear-gradient": "^2.5.6",
"react-native-modal": "^13.0.1",
"react-native-modal-dropdown": "^1.0.0",
"react-native-neomorph-shadows": "^1.1.2",
"react-native-otp-verify": "^1.0.4",
"react-native-pager-view": "^5.1.9",
"react-native-progress": "^5.0.0",
"react-native-radial-gradient": "^1.0.9",
"react-native-reanimated": "2.6.0",
"react-native-render-html": "^6.3.4",
"react-native-safe-area-context": "^3.2.0",
"react-native-screens": "^3.1.1",
"react-native-shimmer-placeholder": "^2.0.7",
"react-native-simple-toast": "^1.1.3",
"react-native-size-matters": "^0.4.0",
"react-native-smooth-picker": "^1.1.5",
"react-native-splash-screen": "^3.2.0",
"react-native-svg": "^12.1.1",
"react-native-svg-transformer": "^0.14.3",
"react-native-tab-view": "^3.0.1",
"react-native-tracking-transparency": "^0.1.1",
"react-native-ultimate-config": "^3.3.4",
"react-native-version-info": "^1.1.0",
"react-native-video": "^5.2.0",
"react-native-walkthrough-tooltip": "^1.3.0",
"react-native-webview": "^11.4.0",
"react-native-wheel-scrollview-picker": "^2.0.0",
"react-redux": "^7.2.3",
"redux-flipper": "^1.4.2",
"redux-logger": "^3.0.6",
"redux-persist": "^6.0.0",
"yup": "^0.32.9"
},```
I got the same issue when using @react-native-community/datetimepicker@6.3.3
. but there was no issue with @react-native-community/datetimepicker@6.3.2
. there was only one change added to 6.3.3
: https://github.com/react-native-datetimepicker/datetimepicker/releases/tag/v6.3.3.
the app hangs (sometimes) when focusing on the input with DateTimePicker.
I tried with reanimated 2.10.0, 2.11.0 and 3.0.0-rc.3.
the crash logs are very similar to what @cltnschlosser had:
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x7fff60c529b6 semaphore_wait_trap + 10
1 libdispatch.dylib 0x7fff201069a0 _dispatch_sema4_wait + 16
2 libdispatch.dylib 0x7fff20106e9f _dispatch_semaphore_wait_slow + 98
3 MyApp 0x10bd4fcbd -[REANodesManager performOperations] + 429 (REANodesManager.m:277)
4 MyApp 0x10bd4f927 -[REANodesManager onAnimationFrame:] + 791 (REANodesManager.m:225)
5 QuartzCore 0x7fff2794a369 CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 755
6 QuartzCore 0x7fff27a2fd78 display_timer_callback(__CFMachPort*, void*, long, void*) + 639
7 CoreFoundation 0x7fff2035c9d8 __CFMachPortPerform + 157
8 CoreFoundation 0x7fff2038fc82 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
9 CoreFoundation 0x7fff2038f023 __CFRunLoopDoSource1 + 614
10 CoreFoundation 0x7fff203894f2 __CFRunLoopRun + 2353
11 CoreFoundation 0x7fff203886d6 CFRunLoopRunSpecific + 567
12 GraphicsServices 0x7fff2bededb3 GSEventRunModal + 139
13 UIKitCore 0x7fff24690e0b -[UIApplication _run] + 912
14 UIKitCore 0x7fff24695cbc UIApplicationMain + 101
15 MyApp 0x10b53b328 main + 104 (main.m:8)
16 dyld 0x11a84652e start + 462
Thread 2:: Dispatch queue: com.facebook.react.ShadowQueue
0 libsystem_kernel.dylib 0x7fff60c540ea __ulock_wait + 10
1 libdispatch.dylib 0x7fff20106d09 _dlock_wait + 44
2 libdispatch.dylib 0x7fff20106b6c _dispatch_thread_event_wait_slow + 40
3 libdispatch.dylib 0x7fff20113e68 __DISPATCH_WAIT_FOR_QUEUE__ + 316
4 libdispatch.dylib 0x7fff201139ec _dispatch_sync_f_slow + 199
5 MyApp 0x10bc5e38e RNDateTimePickerShadowViewMeasure + 238 (RNDateTimePickerShadowView.m:39)
6 MyApp 0x10c25fb35 YGNode::measure(float, YGMeasureMode, float, YGMeasureMode, void*) + 133 (YGNode.cpp:175)
7 MyApp 0x10c276679 YGNodeWithMeasureFuncSetMeasuredDimensions(YGNode*, float, float, YGMeasureMode, YGMeasureMode, float, float, facebook::yoga::LayoutData&, void*, facebook::yoga::LayoutPassReason) + 761 (Yoga.cpp:1692)
8 MyApp 0x10c26e443 YGNodelayoutImpl(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int, facebook::yoga::LayoutPassReason) + 1171 (Yoga.cpp:2761)
9 MyApp 0x10c26da5c YGLayoutNodeInternal(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, facebook::yoga::LayoutPassReason, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 2172 (Yoga.cpp:3917)
10 MyApp 0x10c27ae11 YGNodeComputeFlexBasisForChild(YGNode*, YGNode*, float, YGMeasureMode, float, float, float, YGMeasureMode, YGDirection, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 2865 (Yoga.cpp:1410)
11 MyApp 0x10c2771c2 YGNodeComputeFlexBasisForChildren(YGNode*, float, float, YGMeasureMode, YGMeasureMode, YGDirection, YGFlexDirection, YGConfig*, bool, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 1010 (Yoga.cpp:1930)
12 MyApp 0x10c26e8ce YGNodelayoutImpl(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int, facebook::yoga::LayoutPassReason) + 2334 (Yoga.cpp:2859)
13 MyApp 0x10c26da5c YGLayoutNodeInternal(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, facebook::yoga::LayoutPassReason, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 2172 (Yoga.cpp:3917)
14 MyApp 0x10c27ae11 YGNodeComputeFlexBasisForChild(YGNode*, YGNode*, float, YGMeasureMode, float, float, float, YGMeasureMode, YGDirection, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 2865 (Yoga.cpp:1410)
15 MyApp 0x10c2771c2 YGNodeComputeFlexBasisForChildren(YGNode*, float, float, YGMeasureMode, YGMeasureMode, YGDirection, YGFlexDirection, YGConfig*, bool, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 1010 (Yoga.cpp:1930)
16 MyApp 0x10c26e8ce YGNodelayoutImpl(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int, facebook::yoga::LayoutPassReason) + 2334 (Yoga.cpp:2859)
17 MyApp 0x10c26da5c YGLayoutNodeInternal(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, facebook::yoga::LayoutPassReason, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 2172 (Yoga.cpp:3917)
18 MyApp 0x10c27ae11 YGNodeComputeFlexBasisForChild(YGNode*, YGNode*, float, YGMeasureMode, float, float, float, YGMeasureMode, YGDirection, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 2865 (Yoga.cpp:1410)
19 MyApp 0x10c2771c2 YGNodeComputeFlexBasisForChildren(YGNode*, float, float, YGMeasureMode, YGMeasureMode, YGDirection, YGFlexDirection, YGConfig*, bool, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 1010 (Yoga.cpp:1930)
20 MyApp 0x10c26e8ce YGNodelayoutImpl(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int, facebook::yoga::LayoutPassReason) + 2334 (Yoga.cpp:2859)
21 MyApp 0x10c26da5c YGLayoutNodeInternal(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, facebook::yoga::LayoutPassReason, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 2172 (Yoga.cpp:3917)
22 MyApp 0x10c27ae11 YGNodeComputeFlexBasisForChild(YGNode*, YGNode*, float, YGMeasureMode, float, float, float, YGMeasureMode, YGDirection, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 2865 (Yoga.cpp:1410)
23 MyApp 0x10c2771c2 YGNodeComputeFlexBasisForChildren(YGNode*, float, float, YGMeasureMode, YGMeasureMode, YGDirection, YGFlexDirection, YGConfig*, bool, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 1010 (Yoga.cpp:1930)
24 MyApp 0x10c26e8ce YGNodelayoutImpl(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int, facebook::yoga::LayoutPassReason) + 2334 (Yoga.cpp:2859)
25 MyApp 0x10c26da5c YGLayoutNodeInternal(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, facebook::yoga::LayoutPassReason, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 2172 (Yoga.cpp:3917)
26 MyApp 0x10c2796d5 YGNodeAbsoluteLayoutChild(YGNode*, YGNode*, float, YGMeasureMode, float, YGDirection, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 1781 (Yoga.cpp:1538)
27 MyApp 0x10c271774 YGNodelayoutImpl(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int, facebook::yoga::LayoutPassReason) + 14276 (Yoga.cpp:3522)
28 MyApp 0x10c26da5c YGLayoutNodeInternal(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, facebook::yoga::LayoutPassReason, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 2172 (Yoga.cpp:3917)
29 MyApp 0x10c2797f2 YGNodeAbsoluteLayoutChild(YGNode*, YGNode*, float, YGMeasureMode, float, YGDirection, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 2066 (Yoga.cpp:1560)
30 MyApp 0x10c271774 YGNodelayoutImpl(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int, facebook::yoga::LayoutPassReason) + 14276 (Yoga.cpp:3522)
31 MyApp 0x10c26da5c YGLayoutNodeInternal(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, facebook::yoga::LayoutPassReason, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 2172 (Yoga.cpp:3917)
32 MyApp 0x10c26faf1 YGNodelayoutImpl(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int, facebook::yoga::LayoutPassReason) + 6977 (Yoga.cpp:3165)
33 MyApp 0x10c26da5c YGLayoutNodeInternal(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, facebook::yoga::LayoutPassReason, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 2172 (Yoga.cpp:3917)
34 MyApp 0x10c26faf1 YGNodelayoutImpl(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int, facebook::yoga::LayoutPassReason) + 6977 (Yoga.cpp:3165)
35 MyApp 0x10c26da5c YGLayoutNodeInternal(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, facebook::yoga::LayoutPassReason, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 2172 (Yoga.cpp:3917)
36 MyApp 0x10c26faf1 YGNodelayoutImpl(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int, facebook::yoga::LayoutPassReason) + 6977 (Yoga.cpp:3165)
37 MyApp 0x10c26da5c YGLayoutNodeInternal(YGNode*, float, float, YGDirection, YGMeasureMode, YGMeasureMode, float, float, bool, facebook::yoga::LayoutPassReason, YGConfig*, facebook::yoga::LayoutData&, void*, unsigned int, unsigned int) + 2172 (Yoga.cpp:3917)
38 MyApp 0x10c271eda YGNodeCalculateLayoutWithContext + 1178 (Yoga.cpp:4173)
39 MyApp 0x10c272ea3 YGNodeCalculateLayout + 51 (Yoga.cpp:4271)
40 MyApp 0x10bf15b1a -[RCTShadowView layoutWithMinimumSize:maximumSize:layoutDirection:layoutContext:] + 314 (RCTShadowView.m:279)
41 MyApp 0x10bf01690 -[RCTRootShadowView layoutWithAffectedShadowViews:] + 288 (RCTRootShadowView.m:35)
42 MyApp 0x10bd5f9c3 -[REAUIManager uiBlockWithLayoutUpdateForRootView:] + 163 (REAUIManager.mm:163)
43 MyApp 0x10bf3e62a -[RCTUIManager _layoutAndMount] + 442 (RCTUIManager.m:1165)
44 MyApp 0x10bf3e461 -[RCTUIManager batchDidComplete] + 33 (RCTUIManager.m:1148)
45 MyApp 0x10be7b3e7 __32-[RCTCxxBridge batchDidComplete]_block_invoke + 71 (RCTCxxBridge.mm:1573)
46 libdispatch.dylib 0x7fff2010532f _dispatch_call_block_and_release + 12
47 libdispatch.dylib 0x7fff20106508 _dispatch_client_callout + 8
48 libdispatch.dylib 0x7fff2010c3f9 _dispatch_lane_serial_drain + 715
49 libdispatch.dylib 0x7fff2010cf74 _dispatch_lane_invoke + 403
50 libdispatch.dylib 0x7fff20117577 _dispatch_workloop_worker_thread + 782
51 libsystem_pthread.dylib 0x7fff60c96fd0 _pthread_wqthread + 326
52 libsystem_pthread.dylib 0x7fff60c95f57 start_wqthread + 15
@smikheiev Yeah it’s the same bug, reanimated holding the main thread makes this code (new to 6.3.3 of date time picker) unsafe:
static YGSize RNDateTimePickerShadowViewMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode)
{
RNDateTimePickerShadowView *shadowPickerView = (__bridge RNDateTimePickerShadowView *)YGNodeGetContext(node);
__block CGSize size;
dispatch_sync(dispatch_get_main_queue(), ^{
[shadowPickerView.picker setDate:shadowPickerView.date];
[shadowPickerView.picker setDatePickerMode:shadowPickerView.mode];
[shadowPickerView.picker setLocale:shadowPickerView.locale];
if (@available(iOS 14.0, *)) {
[shadowPickerView.picker setPreferredDatePickerStyle:shadowPickerView.displayIOS];
}
size = [shadowPickerView.picker sizeThatFits:UILayoutFittingCompressedSize];
});
I got the same issue for using "react-native-reanimated": "1.13.3" & "react-native": "0.64.2". But i didn't found any solution for that. Any update on this issue ?
Facing the same issue in reanimated v3.0.2. Any help to fix this issue? @cltnschlosser @ajsmth @tomekzaw @EmmanuelSalazarID Did you guys find a solution?
"react-native-reanimated": "^3.1.0",
same here: 2023-05-10 02:11:32.575475+0200 baby_music[39315:2687260] Assertion failure in -[REANodesManager uiManager:performMountingWithBlock:](), /Users/simo97/Desktop/baby_music/node_modules/react-native-reanimated/ios/REANodesManager.mm:246 2023-05-10 02:11:32.576152+0200 baby_music[39315:2687260] Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Mouting block is expected to not be set' *** First throw call stack: (0x1a6776d94 0x19f82c3d0 0x1a0f21808 0x102807534 0x1029bcd94 0x1029b7bcc 0x1029b7928 0x1029b76a4 0x102806a6c 0x102807c18 0x1029bd5c4 0x105f50520 0x105f52038 0x105f5a0b0 0x105f5adf4 0x105f67c74 0x206103ddc 0x206103b7c) (lldb)
Facing same issue
You can apply this patch, then it works (somewhere is an open PR for this):
react-native-reanimated+3.1.0.patch
diff --git a/node_modules/react-native-reanimated/ios/REANodesManager.mm b/node_modules/react-native-reanimated/ios/REANodesManager.mm
index 26bb253..10e6028 100644
--- a/node_modules/react-native-reanimated/ios/REANodesManager.mm
+++ b/node_modules/react-native-reanimated/ios/REANodesManager.mm
@@ -85,19 +85,77 @@ using namespace facebook::react;
@end
-@interface REANodesManager () <RCTUIManagerObserver>
+#ifndef RCT_NEW_ARCH_ENABLED
+@interface REASyncUpdateObserver : NSObject <RCTUIManagerObserver>
@end
+@implementation REASyncUpdateObserver {
+ volatile void (^_mounting)(void);
+ volatile BOOL _waitTimedOut;
+ dispatch_semaphore_t _semaphore;
+}
+
+- (instancetype)init
+{
+ self = [super init];
+ if (self) {
+ _mounting = nil;
+ _waitTimedOut = NO;
+ _semaphore = dispatch_semaphore_create(0);
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ RCTAssert(_mounting == nil, @"Mouting block was set but never executed. This may lead to UI inconsistencies");
+}
+
+- (void)unblockUIThread
+{
+ RCTAssertUIManagerQueue();
+ dispatch_semaphore_signal(_semaphore);
+}
+
+- (void)waitAndMountWithTimeout:(NSTimeInterval)timeout
+{
+ RCTAssertMainQueue();
+ long result = dispatch_semaphore_wait(_semaphore, dispatch_time(DISPATCH_TIME_NOW, timeout * NSEC_PER_SEC));
+ if (result != 0) {
+ @synchronized(self) {
+ _waitTimedOut = YES;
+ }
+ }
+ if (_mounting) {
+ _mounting();
+ _mounting = nil;
+ }
+}
+
+- (BOOL)uiManager:(RCTUIManager *)manager performMountingWithBlock:(RCTUIManagerMountingBlock)block
+{
+ RCTAssertUIManagerQueue();
+ @synchronized(self) {
+ if (_waitTimedOut) {
+ return NO;
+ } else {
+ _mounting = block;
+ return YES;
+ }
+ }
+}
+
+@end
+
+#endif
+
@implementation REANodesManager {
CADisplayLink *_displayLink;
BOOL _wantRunUpdates;
NSMutableArray<REAOnAnimationCallback> *_onAnimationCallbacks;
BOOL _tryRunBatchUpdatesSynchronously;
REAEventHandler _eventHandler;
- volatile void (^_mounting)(void);
- NSObject *_syncLayoutUpdatesWaitLock;
- volatile BOOL _syncLayoutUpdatesWaitTimedOut;
NSMutableDictionary<NSNumber *, ComponentUpdate *> *_componentUpdateBuffer;
NSMutableDictionary<NSNumber *, UIView *> *_viewRegistry;
#ifdef RCT_NEW_ARCH_ENABLED
@@ -125,7 +183,6 @@ using namespace facebook::react;
_operationsInBatch = [NSMutableDictionary new];
_componentUpdateBuffer = [NSMutableDictionary new];
_viewRegistry = [_uiManager valueForKey:@"_viewRegistry"];
- _syncLayoutUpdatesWaitLock = [NSObject new];
}
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(onAnimationFrame:)];
@@ -241,19 +298,6 @@ using namespace facebook::react;
}
}
-- (BOOL)uiManager:(RCTUIManager *)manager performMountingWithBlock:(RCTUIManagerMountingBlock)block
-{
- RCTAssert(_mounting == nil, @"Mouting block is expected to not be set");
- @synchronized(_syncLayoutUpdatesWaitLock) {
- if (_syncLayoutUpdatesWaitTimedOut) {
- return NO;
- } else {
- _mounting = block;
- return YES;
- }
- }
-}
-
- (void)performOperations
{
#ifdef RCT_NEW_ARCH_ENABLED
@@ -268,8 +312,7 @@ using namespace facebook::react;
_tryRunBatchUpdatesSynchronously = NO;
__weak __typeof__(self) weakSelf = self;
- dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
- _syncLayoutUpdatesWaitTimedOut = NO;
+ REASyncUpdateObserver *syncUpdateObserver = [REASyncUpdateObserver new];
RCTExecuteOnUIManagerQueue(^{
__typeof__(self) strongSelf = weakSelf;
if (strongSelf == nil) {
@@ -278,7 +321,7 @@ using namespace facebook::react;
BOOL canUpdateSynchronously = trySynchronously && ![strongSelf.uiManager hasEnqueuedUICommands];
if (!canUpdateSynchronously) {
- dispatch_semaphore_signal(semaphore);
+ [syncUpdateObserver unblockUIThread];
}
for (int i = 0; i < copiedOperationsQueue.count; i++) {
@@ -286,8 +329,8 @@ using namespace facebook::react;
}
if (canUpdateSynchronously) {
- [strongSelf.uiManager runSyncUIUpdatesWithObserver:strongSelf];
- dispatch_semaphore_signal(semaphore);
+ [strongSelf.uiManager runSyncUIUpdatesWithObserver:syncUpdateObserver];
+ [syncUpdateObserver unblockUIThread];
}
// In case canUpdateSynchronously=true we still have to send uiManagerWillPerformMounting event
// to observers because some components (e.g. TextInput) update their UIViews only on that event.
@@ -298,17 +341,7 @@ using namespace facebook::react;
// from CADisplayLink but it is easier to hardcode it for the time being.
// The reason why we use frame duration here is that if takes longer than one frame to complete layout tasks
// there is no point of synchronizing layout with the UI interaction as we get that one frame delay anyways.
- long result = dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 16 * NSEC_PER_MSEC));
- if (result != 0) {
- @synchronized(_syncLayoutUpdatesWaitLock) {
- _syncLayoutUpdatesWaitTimedOut = YES;
- }
- }
- }
-
- if (_mounting) {
- _mounting();
- _mounting = nil;
+ [syncUpdateObserver waitAndMountWithTimeout:0.016];
}
}
_wantRunUpdates = NO;
Any update on this? If it gets fixed, will it get released on 2.x.x?
Yes, we are getting similar issue. Can this be released in 2.x.x?
Facing same issue "react-native-reanimated": "2.17.0"
Facing same issue too "react-native-reanimated": "2.17.0"
This issue is fixed with - https://github.com/software-mansion/react-native-reanimated/pull/4403. Available in the newest version of Reanimated 3
Description
performOperations blocks the main queue while waiting for the UIManager queue to do work. It's possible that the UIManager queue is already blocked waiting to perform work on the main queue (See somewhat common usage of
RCTUnsafeExecuteOnMainQueueSync
). This can result in deadlock like the following:There is some documentation in
RCTUIManagerUtils.h
on the threading model of this system. There is a noteworthy piece here:What is happening in
performOperations
is effectively a custom implementation ofRCTUnsafeExecuteOnMainQueueSync
and so we get deadlock.This logic was introduced with https://github.com/software-mansion/react-native-reanimated/pull/1215, I don't fully understand the issue this was fixing or why this needed to be synchronously waiting, but there atleast is a connected issue with some context.
This pull request https://github.com/software-mansion/react-native-reanimated/pull/3082 could "fix" the issue by breaking the deadlock, but I'm thinking more could be improved here instead of just timing out the deadlock. It's also not clear to me what happens when this runs asynchronously instead of synchronously.
Potentially related: https://github.com/software-mansion/react-native-reanimated/issues/2938, https://github.com/software-mansion/react-native-reanimated/issues/2327 This same logic is also on Android, which is likely the root cause of https://github.com/software-mansion/react-native-reanimated/issues/3062 and https://github.com/software-mansion/react-native-reanimated/issues/2251
Expected behavior
Never deadlock. Generally best practice is to never block the main thread.
Actual behavior & steps to reproduce
performOperations blocks the main queue waiting on the UIManager queue. It's possible that at this same time the UIManager queue is already blocked trying to perform work on the main queue.
Snack or minimal code example
I don't have anything other than stacktraces showing the deadlock.
Package versions
Affected platforms