From d23c05d42edd453f714d687215c1a10f1aa18959 Mon Sep 17 00:00:00 2001 From: Ibraheem Ahmed Date: Sun, 25 Feb 2024 14:49:54 -0500 Subject: [PATCH] fix race between block initialization and receiver disconnection --- crossbeam-channel/src/flavors/list.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/crossbeam-channel/src/flavors/list.rs b/crossbeam-channel/src/flavors/list.rs index b74c8b33f..354569c00 100644 --- a/crossbeam-channel/src/flavors/list.rs +++ b/crossbeam-channel/src/flavors/list.rs @@ -598,6 +598,7 @@ impl Channel { 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 { @@ -624,8 +625,16 @@ impl Channel { drop(Box::from_raw(block)); } } + head &= !MARK_BIT; - self.head.block.store(ptr::null_mut(), Ordering::Release); + let new_block = self.head.block.swap(ptr::null_mut(), Ordering::AcqRel); + + // If the block was just initalized before the sender saw the MARK_BIT, + // there are no messages but we have to deallocate the block + if block.is_null() && tail >> SHIFT == 0 && !new_block.is_null() { + unsafe { drop(Box::from_raw(new_block)) }; + } + self.head.index.store(head, Ordering::Release); }