Skip to content

Conversation

@stephentoub
Copy link
Member

Fixes #123544

Copilot AI review requested due to automatic review settings January 23, 2026 19:02
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-threading-channels
See info in area-owners.md if you want to be subscribed.

Copy link
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

This pull request fixes a race condition in UnboundedChannel<T> where ChannelReader.Completion could fail to complete even after all items were read and TryComplete() was called. The race occurred when TryRead dequeued the last item concurrently with TryComplete checking if the queue was empty, causing neither operation to trigger channel completion.

Changes:

  • Added a recheck in TryComplete after releasing the lock to handle the race condition
  • Added a regression test that reproduces the race condition with 100,000 iterations
  • Included TaskTimeoutExtensions.cs helper for test timeout functionality

Reviewed changes

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

File Description
src/libraries/System.Threading.Channels/src/System/Threading/Channels/UnboundedChannel.cs Added recheck logic in TryComplete to complete the channel if the queue becomes empty after releasing the lock, fixing the race condition
src/libraries/System.Threading.Channels/tests/UnboundedChannelTests.cs Added regression test that reproduces the race condition by running concurrent TryRead and TryComplete operations
src/libraries/System.Threading.Channels/tests/System.Threading.Channels.Tests.csproj Added reference to TaskTimeoutExtensions.cs for test timeout support

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.

ChannelReader.Completion does not complete even after all items are read and TryComplete() is called

1 participant