Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Fix BufferBlock race condition between completion and consumption #7246

Merged
merged 1 commit into from
Mar 25, 2016

Conversation

stephentoub
Copy link
Member

A failed test in CI highlighted a rare race condition in the BufferBlock implementation. When a bounded buffer block has postponed messages waiting to be consumed and room becomes available, it’ll queue a task to consume those messages from the relevant sources. It should stop consuming messages after it’s been marked as complete, but if the consuming task is already running when the buffer is marked as complete, it may end up still consuming as many messages as have been postponed due to missing a check in that consuming task for having been marked as completed. The fix is simply to add in that check before dequeueing the next postponed message.

Prior to the fix, I ran the test 1,000,000 times and was able to repro this in 22 of them. After the fix, I could no longer repro it.

(There is still an even more rare but expected race that can occur if the block is in the process of consuming the item from one of its sources and the block being marked as completed, but that's no different than a race between it being marked as completed and another thread adding to the block and is the nature of using these components concurrently.)

Fixes https://github.com/dotnet/corefx/issues/7244
cc: @mellinoe, @AlfredoMS

A failed test in CI highlighted a rare race condition in the BufferBlock implementation.  When a bounded buffer block has room become available and postponed messages waiting to be consumed, it’ll queue a task to consume those messages from the relevant sources.  It should stop consuming messages after it’s been marked as complete, but if the consuming task is already running when the buffer is marked as completed, it may end up still consuming messages due to missing a check for having been marked as completed.  The fix is simply to add in that check before dequeueing the next postponed message.

Prior to the fix, I ran the test 1,000,000 times and was able to repro this in 22 of them.  After the fix, I could no longer repro it.

(There is still an even more rare but expected race that can occur if the block is in the process of consuming the item from one of its sources and the block being marked as completed, but that's no different than a race between it being marked as completed and another thread adding to the block and is the nature of using these components concurrently.)
@mellinoe
Copy link
Contributor

LGTM

@mellinoe mellinoe merged commit fc38379 into dotnet:master Mar 25, 2016
@stephentoub stephentoub deleted the bb_consume_race branch March 26, 2016 01:46
@karelz karelz modified the milestone: 1.0.0-rtm Dec 3, 2016
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
Fix BufferBlock race condition between completion and consumption

Commit migrated from dotnet/corefx@fc38379
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TestSendAsync_DelayedConsume test failed in CI
4 participants