Support bounded channel with bound of 0 (rendezvous)#116097
Support bounded channel with bound of 0 (rendezvous)#116097stephentoub merged 2 commits intodotnet:mainfrom
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR introduces support for rendezvous channels by allowing a bounded capacity of 0, which creates an unbuffered channel where writers and readers synchronize directly. In addition to updating the channel‐creation logic and validations, the PR adds new tests (including RendezvousChannelTests) and modernizes null checks throughout the code.
- Support for rendezvous channels in CreateBounded by treating capacity==0 differently.
- Updated validations in ChannelOptions and related APIs to accept capacity 0.
- New test coverage for unbuffered channels and consistent use of null-check patterns.
Reviewed Changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| TestBase.cs | Added a new ThreeBools property used in test data generation. |
| System.Threading.Channels.Tests.csproj | Added the RendezvousChannelTests.cs file to the project. |
| Stress.cs | Introduced new test cases for the rendezvous channel scenario. |
| RendezvousChannelTests.cs | New test suite verifying the behavior of unbuffered (rendezvous) channels. |
| ChannelTests.cs | Modified tests to reflect the updated capacity validation (negative values only are invalid). |
| Channel.cs & ChannelOptions.cs | Updated channel creation methods and validations to allow capacity == 0, creating a rendezvous channel. |
| BoundedChannel.cs, UnboundedChannel.cs, SingleConsumerUnboundedChannel.cs | Updated null-check style and refined internal logic for consistency. |
| ChannelUtilities.* & AsyncOperation.* | Modernized helper methods and cancellation callbacks with updated null-checks. |
| SingleProducerSingleConsumerQueue.cs | Updated debug assertions using the new null-check style. |
Comments suppressed due to low confidence (3)
src/libraries/System.Threading.Channels/tests/RendezvousChannelTests.cs:23
- [nitpick] The tests for the rendezvous channel cover core behaviors; consider adding additional cancellation tests specific to unbuffered channels to ensure robust behavior under cancellation conditions.
Channel<int> c = CreateChannel<int>();
src/libraries/System.Threading.Channels/src/System/Threading/Channels/Channel.cs:40
- Please confirm that changing the capacity validation to support capacity == 0 for rendezvous channels has been fully tested, as this alters the API behavior by allowing unbuffered channels.
public static Channel<T> CreateBounded<T>(int capacity) =>
src/libraries/System.Threading.Channels/src/System/Threading/Channels/ChannelOptions.cs:70
- The updated validation for Capacity now permits a value of 0; please ensure that the documentation reflects that a capacity of 0 indicates a rendezvous channel.
if (value < 0)
There was a problem hiding this comment.
Pull Request Overview
This PR adds support for zero-capacity (rendezvous) bounded channels by routing CreateBounded(0) to a new RendezvousChannel implementation, updates validation to allow zero bounds, and introduces tests covering rendezvous behavior.
- Update
Channel.CreateBoundedto handlecapacity == 0 - Add
RendezvousChannelimplementation and extensive rendezvous tests - Adjust options validation and test code for asynchronous writes
Reviewed Changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/libraries/System.Threading.Channels/src/System/Threading/Channels/Channel.cs | Routes capacity == 0 to RendezvousChannel |
| src/libraries/System.Threading.Channels/src/System/Threading/Channels/ChannelOptions.cs | Changed capacity check to allow 0; updated exception docs |
| src/libraries/System.Threading.Channels/tests/RendezvousChannelTests.cs | New tests for rendezvous channels |
| src/libraries/System.Threading.Channels/tests/Stress.cs | Added rendezvous stress test variations |
| src/libraries/System.Threading.Channels/src/System/Threading/Channels/ChannelUtilities.cs | Added unused CountOperations helper |
Comments suppressed due to low confidence (2)
src/libraries/System.Threading.Channels/tests/Stress.cs:65
- Rendezvous tests currently only cover
WaitandDropWritemodes. Consider addingDropOldestandDropNewestto ensure full-mode behaviors are validated for zero-capacity channels.
foreach (var bcfm in new[] { BoundedChannelFullMode.Wait, BoundedChannelFullMode.DropWrite })
src/libraries/System.Threading.Channels/tests/Stress.cs:65
- [nitpick] The local variable
bcfmis abbreviated and may not convey its purpose clearly. Consider renaming it tofullModefor readability.
foreach (var bcfm in new[] { BoundedChannelFullMode.Wait, BoundedChannelFullMode.DropWrite })
This PR enables Channel.CreateBounded(0), whereas currently a bound of < 1 is exceptional. A bound is the number of items the channel can buffer, so a bound of 0 means it can't buffer anything, which makes it into a rendezvous, where the reader and writer must be at the channel at the same time in order to directly hand off from the writer to the reader. This is the same meaning as in other languages/libraries, e.g. if in go you don't specify a bound or you specify a bound of 0, you similarly get an unbuffered rendezvous channel.
|
/ba-g unrelated test infra failure |
|
We brought back unbuffered channels?! Nice |
Closes #94046.
This PR enables Channel.CreateBounded(0), whereas currently a bound of < 1 is exceptional. A bound is the number of items the channel can buffer, so a bound of 0 means it can't buffer anything, which makes it into a rendezvous, where the reader and writer must be at the channel at the same time in order to directly hand off from the writer to the reader. This is the same meaning as in other languages/libraries, e.g. if in go you don't specify a bound or you specify a bound of 0, you similarly get an unbuffered rendezvous channel.