Skip to content

Fix TSAN data races in InspectorFlags and InspectorPackagerConnection (#56534)#56534

Closed
javache wants to merge 1 commit intofacebook:mainfrom
javache:export-D101809616
Closed

Fix TSAN data races in InspectorFlags and InspectorPackagerConnection (#56534)#56534
javache wants to merge 1 commit intofacebook:mainfrom
javache:export-D101809616

Conversation

@javache
Copy link
Copy Markdown
Member

@javache javache commented Apr 21, 2026

Summary:

Fix two ThreadSanitizer data races caught by the messenger_demo integration test under dev-tsan mode.

InspectorFlags: loadFlagsAndAssertUnchanged() reads and writes cachedValues_ without synchronization. The main thread calls it via getIsProfilingBuild() while the JS thread calls it via getNetworkInspectionEnabled(), racing on the shared optional<Values>. Add a std::mutex to protect cachedValues_ access. The lock is taken after computing newValues from feature flags, so flag reads stay outside the critical section. dangerouslyResetFlags() also acquires the lock to avoid racing with concurrent flag reads.

Inspector: Inspector::connectDebugger() is called from the main thread but creates and uses packagerConnection_ which is also accessed on the inspector thread. Dispatch the body of connectDebugger() to the task dispatch thread via invokeElsePost(), matching the pattern other Inspector methods already use. This ensures InspectorPackagerConnection::connect() is called on the correct thread as its API requires.

Changelog: [Internal]

Reviewed By: hoxyq

Differential Revision: D101809616

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Apr 21, 2026
@meta-codesync
Copy link
Copy Markdown

meta-codesync Bot commented Apr 21, 2026

@javache has exported this pull request. If you are a Meta employee, you can view the originating Diff in D101809616.

@meta-codesync meta-codesync Bot changed the title Fix TSAN data races in InspectorFlags and InspectorPackagerConnection Fix TSAN data races in InspectorFlags and InspectorPackagerConnection (#56534) Apr 22, 2026
@javache javache force-pushed the export-D101809616 branch from ecd5c35 to bd0175d Compare April 22, 2026 16:33
javache added a commit to javache/react-native that referenced this pull request Apr 22, 2026
…facebook#56534)

Summary:

Fix two ThreadSanitizer data races caught by the messenger_demo integration test under dev-tsan mode.

**InspectorFlags**: `loadFlagsAndAssertUnchanged()` reads and writes `cachedValues_` without synchronization. The main thread calls it via `getIsProfilingBuild()` while the JS thread calls it via `getNetworkInspectionEnabled()`, racing on the shared `optional<Values>`. Add a `std::mutex` to protect `cachedValues_` access. The lock is taken after computing `newValues` from feature flags, so flag reads stay outside the critical section.

**InspectorPackagerConnection**: `Impl::connect()` is called from the main thread but accesses `webSocket_` which is also read by `didFailWithError()` on the inspector thread. Dispatch the body of `connect()` to the inspector thread via `scheduleCallback()`, matching the pattern `reconnect()` already uses.

Changelog: [Internal]

Differential Revision: D101809616
@javache javache force-pushed the export-D101809616 branch from bd0175d to 3218ed5 Compare April 24, 2026 09:32
javache added a commit to javache/react-native that referenced this pull request Apr 24, 2026
…facebook#56534)

Summary:

Fix two ThreadSanitizer data races caught by the messenger_demo integration test under dev-tsan mode.

**InspectorFlags**: `loadFlagsAndAssertUnchanged()` reads and writes `cachedValues_` without synchronization. The main thread calls it via `getIsProfilingBuild()` while the JS thread calls it via `getNetworkInspectionEnabled()`, racing on the shared `optional<Values>`. Add a `std::mutex` to protect `cachedValues_` access. The lock is taken after computing `newValues` from feature flags, so flag reads stay outside the critical section. `dangerouslyResetFlags()` also acquires the lock to avoid racing with concurrent flag reads.

**Inspector**: `Inspector::connectDebugger()` is called from the main thread but creates and uses `packagerConnection_` which is also accessed on the inspector thread. Dispatch the body of `connectDebugger()` to the task dispatch thread via `invokeElsePost()`, matching the pattern other Inspector methods already use. This ensures `InspectorPackagerConnection::connect()` is called on the correct thread as its API requires.

Changelog: [Internal]

Differential Revision: D101809616
@javache javache force-pushed the export-D101809616 branch from 3218ed5 to d5cf4cf Compare April 27, 2026 13:17
javache added a commit to javache/react-native that referenced this pull request Apr 27, 2026
…facebook#56534)

Summary:
Pull Request resolved: facebook#56534

Fix two ThreadSanitizer data races caught by the messenger_demo integration test under dev-tsan mode.

**InspectorFlags**: `loadFlagsAndAssertUnchanged()` reads and writes `cachedValues_` without synchronization. The main thread calls it via `getIsProfilingBuild()` while the JS thread calls it via `getNetworkInspectionEnabled()`, racing on the shared `optional<Values>`. Add a `std::mutex` to protect `cachedValues_` access. The lock is taken after computing `newValues` from feature flags, so flag reads stay outside the critical section. `dangerouslyResetFlags()` also acquires the lock to avoid racing with concurrent flag reads.

**Inspector**: `Inspector::connectDebugger()` is called from the main thread but creates and uses `packagerConnection_` which is also accessed on the inspector thread. Dispatch the body of `connectDebugger()` to the task dispatch thread via `invokeElsePost()`, matching the pattern other Inspector methods already use. This ensures `InspectorPackagerConnection::connect()` is called on the correct thread as its API requires.

Changelog: [Internal]

Differential Revision: D101809616
…facebook#56534)

Summary:

Fix two ThreadSanitizer data races caught by the messenger_demo integration test under dev-tsan mode.

**InspectorFlags**: `loadFlagsAndAssertUnchanged()` reads and writes `cachedValues_` without synchronization. The main thread calls it via `getIsProfilingBuild()` while the JS thread calls it via `getNetworkInspectionEnabled()`, racing on the shared `optional<Values>`. Add a `std::mutex` to protect `cachedValues_` access. The lock is taken after computing `newValues` from feature flags, so flag reads stay outside the critical section. `dangerouslyResetFlags()` also acquires the lock to avoid racing with concurrent flag reads.

**Inspector**: `Inspector::connectDebugger()` is called from the main thread but creates and uses `packagerConnection_` which is also accessed on the inspector thread. Dispatch the body of `connectDebugger()` to the task dispatch thread via `invokeElsePost()`, matching the pattern other Inspector methods already use. This ensures `InspectorPackagerConnection::connect()` is called on the correct thread as its API requires.

Changelog: [Internal]

Reviewed By: hoxyq

Differential Revision: D101809616
@javache javache force-pushed the export-D101809616 branch from d5cf4cf to e2efafd Compare May 1, 2026 10:46
@meta-codesync meta-codesync Bot closed this in 86dbb3b May 1, 2026
@facebook-github-tools facebook-github-tools Bot added the Merged This PR has been merged. label May 1, 2026
@meta-codesync
Copy link
Copy Markdown

meta-codesync Bot commented May 1, 2026

This pull request has been merged in 86dbb3b.

@react-native-bot
Copy link
Copy Markdown
Collaborator

This pull request was successfully merged by @javache in 86dbb3b

When will my fix make it into a release? | How to file a pick request?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported Merged This PR has been merged. meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants