software-mansion / react-native-reanimated

React Native's Animated library reimplemented
https://docs.swmansion.com/react-native-reanimated/
MIT License
8.78k stars 1.28k forks source link

Deadlock in [REANodesManager performOperations] #3180

Closed cltnschlosser closed 8 months ago

cltnschlosser commented 2 years ago

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:

Thread 0 Crashed:
0   libsystem_kernel.dylib          0x00000001b82e7540 semaphore_wait_trap + 8
1   libdispatch.dylib               0x00000001809ffc00 _dispatch_sema4_wait + 28 (lock.c:139)
2   libdispatch.dylib               0x0000000180a002b8 _dispatch_semaphore_wait_slow + 132 (semaphore.c:132)
3   MyApp                           0x0000000104795c64 -[REANodesManager performOperations] + 284 (REANodesManager.m:261)
4   MyApp                           0x0000000104795aa4 -[REANodesManager onAnimationFrame:] + 452 (REANodesManager.m:209)
5   QuartzCore                      0x0000000184a5e378 CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 756 (CADisplay.mm:4177)
6   QuartzCore                      0x0000000184a64fac display_timer_callback(__CFMachPort*, void*, long, void*) + 372 (CADisplayTimer.cpp:219)
7   CoreFoundation                  0x0000000180cff440 __CFMachPortPerform + 176 (CFMachPort.c:549)
8   CoreFoundation                  0x0000000180d427d4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 60 (CFRunLoop.c:1996)
9   CoreFoundation                  0x0000000180d45fe0 __CFRunLoopDoSource1 + 596 (CFRunLoop.c:2136)
10  CoreFoundation                  0x0000000180cffebc __CFRunLoopRun + 2380 (CFRunLoop.c:3172)
11  CoreFoundation                  0x0000000180d13468 CFRunLoopRunSpecific + 600 (CFRunLoop.c:3268)
12  GraphicsServices                0x000000019c8b738c GSEventRunModal + 164 (GSEvent.c:2200)
13  UIKitCore                       0x00000001836b65d0 -[UIApplication _run] + 1100 (UIApplication.m:3493)
14  UIKitCore                       0x0000000183434f74 UIApplicationMain + 364 (UIApplication.m:5047)
15  MyApp                           0x000000010421bf2c main + 68 (AnalyticsKey.swift:29)
16  dyld                            0x0000000105e9daa4 start + 520 (dyldMain.cpp:879)
Thread 12:
0   libsystem_kernel.dylib          0x00000001b82e81a4 __ulock_wait + 8
1   libdispatch.dylib               0x0000000180a00064 _dlock_wait + 56 (lock.c:326)
2   libdispatch.dylib               0x00000001809ffe08 _dispatch_thread_event_wait_slow + 56 (lock.c:366)
3   libdispatch.dylib               0x0000000180a0ebac __DISPATCH_WAIT_FOR_QUEUE__ + 364 (lock.h:330)
4   libdispatch.dylib               0x0000000180a0e754 _dispatch_sync_f_slow + 144 (queue.c:1762)
5   MyApp                           0x0000000104849324 RCTUnsafeExecuteOnMainQueueSync + 120 (RCTUtils.m:277)
6   libdispatch.dylib               0x00000001809ff670 _dispatch_client_callout + 20 (object.m:560)
7   libdispatch.dylib               0x0000000180a00f18 _dispatch_once_callout + 32 (once.c:52)
8   MyApp                           0x00000001048494e4 dispatch_once + 20 (once.h:84)
9   MyApp                           0x00000001048494e4 RCTScreenSize + 68 (RCTUtils.m:343)
10  MyApp                           0x0000000104815898 -[RCTModalHostShadowView insertReactSubview:atIndex:] + 124 (RCTModalHostViewManager.m:42)
11  MyApp                           0x0000000104842ad0 RCTSetChildren + 280 (RCTUIManager.m:884)
12  MyApp                           0x00000001048428e8 -[RCTUIManager setChildren:reactTags:] + 68 (RCTUIManager.m:865)
13  CoreFoundation                  0x0000000180d163a4 __invoking___ + 148
14  CoreFoundation                  0x0000000180d33b74 -[NSInvocation invoke] + 468 (NSForwarding.m:3378)
15  CoreFoundation                  0x0000000180d6a9d4 -[NSInvocation invokeWithTarget:] + 80 (NSForwarding.m:3475)
16  MyApp                           0x000000010481b928 -[RCTModuleMethod invokeWithBridge:module:arguments:] + 460 (RCTModuleMethod.mm:584)
17  MyApp                           0x000000010481df2c facebook::react::invokeInner(RCTBridge*, RCTModuleData*, unsigned int, folly::dynamic const&, int, (anonymous namespace)::SchedulingContext) + 540 (RCTNativeModule.mm:183)
18  MyApp                           0x000000010481db5c operator() + 68 (RCTNativeModule.mm:104)
19  MyApp                           0x000000010481db5c invocation function for block in facebook::react::RCTNativeModule::invoke(unsigned int, folly::dynamic&&, int) + 112 (RCTNativeModule.mm:95)
20  libdispatch.dylib               0x00000001809fd924 _dispatch_call_block_and_release + 32 (init.c:1517)
21  libdispatch.dylib               0x00000001809ff670 _dispatch_client_callout + 20 (object.m:560)
22  libdispatch.dylib               0x0000000180a06df4 _dispatch_lane_serial_drain + 672 (inline_internal.h:2601)
23  libdispatch.dylib               0x0000000180a07968 _dispatch_lane_invoke + 392 (queue.c:3937)
24  libdispatch.dylib               0x0000000180a121b8 _dispatch_workloop_worker_thread + 656 (queue.c:6727)
25  libsystem_pthread.dylib         0x00000001f181b0f4 _pthread_wqthread + 288 (pthread.c:2599)
26  libsystem_pthread.dylib         0x00000001f181ae94 start_wqthread + 8

There is some documentation in RCTUIManagerUtils.h on the threading model of this system. There is a noteworthy piece here:

This solution assumes that the code running on UIManager queue will never explicitly block the Main queue via calling RCTUnsafeExecuteOnMainQueueSync. Otherwise, it can cause a deadlock.

What is happening in performOperations is effectively a custom implementation of RCTUnsafeExecuteOnMainQueueSync 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

name version
react-native 0.66.4
react-native-reanimated 2.4.1 (with https://github.com/software-mansion/react-native-reanimated/pull/2681 applied)
NodeJS 16.14.2
Xcode 13.3.1

Affected platforms

github-actions[bot] commented 2 years 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?

nazrdogan commented 2 years ago

I have the same issue.

bsonmez commented 2 years ago

same here

egorkhmelev commented 2 years ago

same here

dwnste commented 2 years ago

same error w/ pretty similar stack trace, can only see this behaviour on iOS though. "react-native-reanimated": "^2.5.0"

ericgjackson commented 2 years ago

Also seeing this. iPhone7 and iPad mini. I'm still on react-native-reanimated 2.3.3 though.

AlexanderEggers commented 2 years ago

I can observe this issue using in the latest version (2.8.0) as well.

anhquan291 commented 2 years ago

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"

daxaxelrod commented 2 years ago

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",

ericgjackson commented 2 years ago

Is anyone reviewing cltnschlosser's PR? Or fixing the problem in some other way?

cedricjacobs commented 2 years ago

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 :-)

jp928 commented 2 years ago

Same

cedricjacobs commented 2 years ago

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. :-/

3runoDesign commented 2 years ago

same

lucascardial commented 2 years ago

same here

tomgreco commented 2 years ago

Any update on this?

dandre-hound commented 2 years ago

After merging in this PR locally, we saw a noticeable drop in iOS native app crashes over the last 90 days:

Screen Shot 2022-08-04 at 10 35 03 AM
caopeng000 commented 2 years ago

same here

github-actions[bot] commented 2 years ago

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?

caopeng000 commented 2 years ago

same here "react-native-reanimated": "2.9.1", "react-native": "0.64.2",

EmmanuelSalazarID commented 1 year ago

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",

Captura de Pantalla 2022-08-26 a la(s) 10 07 25

In Pods RNReanimated > ios > REANodesManager > -performOperations Captura de Pantalla 2022-08-26 a la(s) 10 08 30

This crash it doesn't even get caught by Crashlytics

viv3kk commented 1 year ago

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"
  },```
smikheiev commented 1 year ago

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
cltnschlosser commented 1 year ago

@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];
  });
SandeepKumar213 commented 1 year ago

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 ?

malikzype commented 1 year ago

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?

Pnlvfx commented 1 year ago

"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)

sirajtahrawashmen commented 1 year ago

Facing same issue

happyfloat commented 1 year ago

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;
bcgilliom commented 1 year ago

Any update on this? If it gets fixed, will it get released on 2.x.x?

malikzype commented 1 year ago

Yes, we are getting similar issue. Can this be released in 2.x.x?

SergeyKopytov1205 commented 1 year ago

Facing same issue "react-native-reanimated": "2.17.0"

DarkShtir commented 11 months ago

Facing same issue too "react-native-reanimated": "2.17.0"

piaskowyk commented 8 months ago

This issue is fixed with - https://github.com/software-mansion/react-native-reanimated/pull/4403. Available in the newest version of Reanimated 3