Skip to content

Fix reentrant Monitor wait#126071

Merged
eduardo-vp merged 5 commits intodotnet:mainfrom
eduardo-vp:fix-reentrant-monitor-wait-hang
Mar 25, 2026
Merged

Fix reentrant Monitor wait#126071
eduardo-vp merged 5 commits intodotnet:mainfrom
eduardo-vp:fix-reentrant-monitor-wait-hang

Conversation

@eduardo-vp
Copy link
Copy Markdown
Member

@eduardo-vp eduardo-vp commented Mar 25, 2026

Fixes #123173.

There's currently a problem with Monitor using a single thread-static Waiter (and AutoResetEvent) per thread. When using synchronization contexts that allow message pumping the following scenario can happen:

  • The main thread calls Monitor.Wait on lock A.
  • SynchronizationContext.Wait pumps a message and the main thread calls Monitor.Wait on lock B.
  • Since both operations were run on the same thread, both share the same waiter.
  • A background thread calls Monitor.Pulse on lock A but lock B steals the signal since they share the same waiter.

This change nulls out the thread-static Waiter while a wait is in progress, so any reentrant Monitor.Wait gets its own Waiter with a distinct AutoResetEvent. The Waiter is restored after the wait completes.

Copilot AI review requested due to automatic review settings March 25, 2026 03:31
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @agocke, @VSadov
See info in area-owners.md if you want to be subscribed.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a Monitor.Wait reentrancy issue where nested waits on the same thread could share a single thread-static waiter/event, allowing one wait to consume (“steal”) another wait’s pulse, particularly when SynchronizationContext.Wait pumps messages.

Changes:

  • Adjust Condition.Waiter thread-static reuse to clear the cached waiter while a wait is in progress, ensuring overlapping waits use distinct AutoResetEvent instances.
  • Add a regression test that reproduces the message-pumping reentrant wait scenario via a custom SynchronizationContext.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/libraries/System.Private.CoreLib/src/System/Threading/Condition.cs Updates waiter caching logic so overlapping waits don’t share the same thread-static waiter/event.
src/libraries/System.Threading/tests/MonitorTests.cs Adds a regression test validating reentrant waits don’t steal each other’s pulse signals.

…ition.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 25, 2026 03:41
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

@eduardo-vp eduardo-vp requested review from VSadov and jkotas March 25, 2026 03:48
@jkotas jkotas requested a review from jkoritzinsky March 25, 2026 04:10
Copy link
Copy Markdown
Member

@VSadov VSadov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copilot AI review requested due to automatic review settings March 25, 2026 17:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

@eduardo-vp
Copy link
Copy Markdown
Member Author

/ba-g unrelated failures

@eduardo-vp eduardo-vp merged commit d343974 into dotnet:main Mar 25, 2026
135 of 152 checks passed
@eduardo-vp eduardo-vp deleted the fix-reentrant-monitor-wait-hang branch March 25, 2026 23:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[dotnet-sdk-11.0.100-alpha.1.26062.101] No response is observed in ULogViewer after the OK button is clicked.

6 participants