Skip to content

Commit 4642723

Browse files
Copilotanupriya13
andcommitted
Remove sync call from DetachRootView to fix deadlock, add quirk option to re-enable if needed
Co-authored-by: anupriya13 <54227869+anupriya13@users.noreply.github.com>
1 parent 144551a commit 4642723

3 files changed

Lines changed: 19 additions & 8 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "prerelease",
3+
"comment": "Remove sync call from DetachRootView to fix deadlock, add quirk option to re-enable if needed",
4+
"packageName": "@rnw-dependencies",
5+
"email": "noreply@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}

vnext/Microsoft.ReactNative/ReactHost/React.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,12 @@ struct ReactOptions {
251251
//! It is not safe to expose to Custom Function. Add this flag so we can turn it off for Custom Function.
252252
bool EnableNativePerformanceNow{true};
253253

254+
//! QUIRK: Enable synchronous wait in DetachRootView for JS thread completion.
255+
//! This flag re-enables the legacy runOnQueueSync call that can cause deadlocks
256+
//! with Hermes GC. Only enable if removal of sync behavior breaks your application.
257+
//! Default: false (sync call is disabled to prevent deadlocks)
258+
bool EnableSyncDetachRootView{false};
259+
254260
ReactDevOptions DeveloperSettings = {};
255261

256262
//! This controls the availability of various developer support functionality including

vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,15 +1514,13 @@ void ReactInstanceWin::DetachRootView(facebook::react::IReactRootView *rootView,
15141514
CallJsFunction("AppRegistry", "unmountApplicationComponentAtRootTag", std::move(params));
15151515
}
15161516

1517-
// Schedule an async task on the JS thread to ensure previous operations complete
1518-
// This avoids the deadlock that can occur with runOnQueueSync when the JS thread
1519-
// is busy with garbage collection or other operations
1520-
if (auto jsMessageThread = m_jsMessageThread.Load()) {
1521-
jsMessageThread->runOnQueue([]() {
1522-
// This async operation ensures that any previously queued JS operations
1523-
// (like the unmount call above) have a chance to complete
1524-
});
1517+
// QUIRK: Legacy sync behavior can be re-enabled via EnableSyncDetachRootView option
1518+
// The sync call was removed to prevent deadlocks with Hermes GC operations
1519+
if (m_options.EnableSyncDetachRootView) {
1520+
// Legacy behavior: wait for JS thread to finish executing (can cause deadlocks)
1521+
m_jsMessageThread.Load()->runOnQueueSync([]() {});
15251522
}
1523+
// Default behavior: no synchronization call to prevent deadlocks
15261524
}
15271525

15281526
Mso::CntPtr<IReactInstanceInternal> MakeReactInstance(

0 commit comments

Comments
 (0)