diff --git a/crossbeam-channel/CHANGELOG.md b/crossbeam-channel/CHANGELOG.md index 3277f15aa..6a405ee73 100644 --- a/crossbeam-channel/CHANGELOG.md +++ b/crossbeam-channel/CHANGELOG.md @@ -1,17 +1,29 @@ +# Version 0.5.8 + +- Fix race condition in unbounded channel. (#972) + # Version 0.5.7 +**Note:** This release has been yanked due to bug fixed in 0.5.8. + - Improve handling of very large timeout. (#953) # Version 0.5.6 +**Note:** This release has been yanked due to bug fixed in 0.5.8. + - Bump the minimum supported Rust version to 1.38. (#877) # Version 0.5.5 +**Note:** This release has been yanked due to bug fixed in 0.5.8. + - Replace Spinlock with Mutex. (#835) # Version 0.5.4 +**Note:** This release has been yanked due to bug fixed in 0.5.8. + - Workaround a bug in upstream related to TLS access on AArch64 Linux. (#802) # Version 0.5.3 @@ -28,6 +40,8 @@ # Version 0.5.1 +**Note:** This release has been yanked due to bug fixed in 0.5.8. + - Fix memory leak in unbounded channel. (#669) # Version 0.5.0 diff --git a/crossbeam-channel/Cargo.toml b/crossbeam-channel/Cargo.toml index 25c367802..a15528029 100644 --- a/crossbeam-channel/Cargo.toml +++ b/crossbeam-channel/Cargo.toml @@ -4,7 +4,7 @@ name = "crossbeam-channel" # - Update CHANGELOG.md # - Update README.md # - Create "crossbeam-channel-X.Y.Z" git tag -version = "0.5.7" +version = "0.5.8" edition = "2018" rust-version = "1.38" license = "MIT OR Apache-2.0" diff --git a/crossbeam-channel/src/flavors/list.rs b/crossbeam-channel/src/flavors/list.rs index 6090b8d47..230edd8d2 100644 --- a/crossbeam-channel/src/flavors/list.rs +++ b/crossbeam-channel/src/flavors/list.rs @@ -584,6 +584,17 @@ impl Channel { let mut head = self.head.index.load(Ordering::Acquire); let mut block = self.head.block.load(Ordering::Acquire); + // If we're going to be dropping messages we need to synchronize with initialization + if head >> SHIFT != tail >> SHIFT { + // The block can be null here only if a sender is in the process of initializing the + // channel while another sender managed to send a message by inserting it into the + // semi-initialized channel and advanced the tail. + // In that case, just wait until it gets initialized. + while block.is_null() { + backoff.snooze(); + block = self.head.block.load(Ordering::Acquire); + } + } unsafe { // Drop all messages between head and tail and deallocate the heap-allocated blocks. while head >> SHIFT != tail >> SHIFT {