This is an automated email from the git hooks/post-receive script.
pierov pushed a commit to branch geckoview-99.0.1-11.0-1 in repository tor-browser.
commit 5f0fafc48ec91248b7c88378ff9c94465e208082 Author: Mike Hommey mh+mozilla@glandium.org AuthorDate: Thu Mar 24 06:08:27 2022 +0000
Bug 1757571 - Upgrade crossbeam-channel to 0.5.4. r=emilio a=dmeehan
Differential Revision: https://phabricator.services.mozilla.com/D141563 --- Cargo.lock | 4 +- .../rust/crossbeam-channel/.cargo-checksum.json | 2 +- third_party/rust/crossbeam-channel/CHANGELOG.md | 12 ++- third_party/rust/crossbeam-channel/Cargo.lock | 28 +++---- third_party/rust/crossbeam-channel/Cargo.toml | 18 ++++- third_party/rust/crossbeam-channel/src/channel.rs | 5 +- third_party/rust/crossbeam-channel/src/err.rs | 4 - .../rust/crossbeam-channel/src/flavors/array.rs | 56 +++++--------- .../rust/crossbeam-channel/src/flavors/at.rs | 3 +- .../rust/crossbeam-channel/src/flavors/list.rs | 2 +- .../rust/crossbeam-channel/src/flavors/never.rs | 1 - .../rust/crossbeam-channel/src/flavors/tick.rs | 4 +- .../rust/crossbeam-channel/src/flavors/zero.rs | 3 +- third_party/rust/crossbeam-channel/src/select.rs | 17 +++-- .../rust/crossbeam-channel/src/select_macro.rs | 58 +-------------- third_party/rust/crossbeam-channel/src/utils.rs | 8 ++ third_party/rust/crossbeam-channel/src/waker.rs | 46 +++++++----- third_party/rust/crossbeam-channel/tests/array.rs | 86 +++++++++++++++++++++- .../rust/crossbeam-channel/tests/select_macro.rs | 11 +++ 19 files changed, 207 insertions(+), 161 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock index 2b23503bd8179..ae2a29270132a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -978,9 +978,9 @@ dependencies = [
[[package]] name = "crossbeam-channel" -version = "0.5.2" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" +checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" dependencies = [ "cfg-if 1.0.0", "crossbeam-utils 0.8.6", diff --git a/third_party/rust/crossbeam-channel/.cargo-checksum.json b/third_party/rust/crossbeam-channel/.cargo-checksum.json index c81ab6c108808..681e643ec45c6 100644 --- a/third_party/rust/crossbeam-channel/.cargo-checksum.json +++ b/third_party/rust/crossbeam-channel/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"e70d1a5fa6697a8b24e193e3934975317df12279c167b90fcb9616291792197c","Cargo.lock":"0f4e59f28bdd52c4781d102fc7d1f16d1ea417aaec0a4846432444a4019b2537","Cargo.toml":"c8334f658b699a1a0e25d997d752a9493a627f9ddcb7aab739c7319ea583882f","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","LICENSE-THIRD-PARTY":"b16db96b93b1d7cf7bea533f572091ec6bca3234fbe0a83038be [...] \ No newline at end of file +{"files":{"CHANGELOG.md":"0f549e63930d1e576f117ee9249c84276eadbe6fb95818680c042c6c0af8a807","Cargo.lock":"834da9468c17c8e1b7fe457764257f4dfdaa24bc98cbdfedf3af4f3d4f5c1e6a","Cargo.toml":"1296a016c4c23d38a35b3d737ee8285fcaaf7d23b7bbb5a3484cefe56b7ca32a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","LICENSE-THIRD-PARTY":"b16db96b93b1d7cf7bea533f572091ec6bca3234fbe0a83038be [...] \ No newline at end of file diff --git a/third_party/rust/crossbeam-channel/CHANGELOG.md b/third_party/rust/crossbeam-channel/CHANGELOG.md index 6bfd92354197a..bf19e261c7103 100644 --- a/third_party/rust/crossbeam-channel/CHANGELOG.md +++ b/third_party/rust/crossbeam-channel/CHANGELOG.md @@ -1,6 +1,14 @@ +# Version 0.5.4 + +- Workaround a bug in upstream related to TLS access on AArch64 Linux. (#802) + +# Version 0.5.3 + +- Fix panic on very large timeout. (#798) + # Version 0.5.2
-- Fix stacked borrows violations. (#763, #764) +- Fix stacked borrows violations when `-Zmiri-tag-raw-pointers` is enabled. (#763, #764)
# Version 0.5.1
@@ -22,6 +30,8 @@
# Version 0.4.3
+**Note**: This release has been yanked. See [CVE-2020-15254](https://github.com/crossbeam-rs/crossbeam/security/advisories/GHSA-v5m7-53cv...) for details. + - Change license to "MIT OR Apache-2.0".
# Version 0.4.2 diff --git a/third_party/rust/crossbeam-channel/Cargo.lock b/third_party/rust/crossbeam-channel/Cargo.lock index feb6e7526aa56..9d374c5170e06 100644 --- a/third_party/rust/crossbeam-channel/Cargo.lock +++ b/third_party/rust/crossbeam-channel/Cargo.lock @@ -10,7 +10,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] name = "crossbeam-channel" -version = "0.5.2" +version = "0.5.4" dependencies = [ "cfg-if", "crossbeam-utils", @@ -21,9 +21,9 @@ dependencies = [
[[package]] name = "crossbeam-utils" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcae03edb34f947e64acdb1c33ec169824e20657e9ecb61cef6c8c74dcb8120" +checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" dependencies = [ "cfg-if", "lazy_static", @@ -31,9 +31,9 @@ dependencies = [
[[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77" dependencies = [ "cfg-if", "libc", @@ -57,9 +57,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] name = "libc" -version = "0.2.112" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" +checksum = "ad5c14e80759d0939d013e6ca49930e59fc53dd8e5009132f76240c179380c09"
[[package]] name = "num_cpus" @@ -79,14 +79,13 @@ checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
[[package]] name = "rand" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", "rand_core", - "rand_hc", ]
[[package]] @@ -108,15 +107,6 @@ dependencies = [ "getrandom", ]
-[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core", -] - [[package]] name = "signal-hook" version = "0.3.13" diff --git a/third_party/rust/crossbeam-channel/Cargo.toml b/third_party/rust/crossbeam-channel/Cargo.toml index 87a889fb73cd1..dc7182de192e6 100644 --- a/third_party/rust/crossbeam-channel/Cargo.toml +++ b/third_party/rust/crossbeam-channel/Cargo.toml @@ -13,13 +13,24 @@ edition = "2018" rust-version = "1.36" name = "crossbeam-channel" -version = "0.5.2" +version = "0.5.4" description = "Multi-producer multi-consumer channels for message passing" homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-channel" -keywords = ["channel", "mpmc", "select", "golang", "message"] -categories = ["algorithms", "concurrency", "data-structures"] +keywords = [ + "channel", + "mpmc", + "select", + "golang", + "message", +] +categories = [ + "algorithms", + "concurrency", + "data-structures", +] license = "MIT OR Apache-2.0" repository = "https://github.com/crossbeam-rs/crossbeam" + [dependencies.cfg-if] version = "1"
@@ -27,6 +38,7 @@ version = "1" version = "0.8" optional = true default-features = false + [dev-dependencies.num_cpus] version = "1.13.0"
diff --git a/third_party/rust/crossbeam-channel/src/channel.rs b/third_party/rust/crossbeam-channel/src/channel.rs index 8988235db45e2..8bd4fe95342c7 100644 --- a/third_party/rust/crossbeam-channel/src/channel.rs +++ b/third_party/rust/crossbeam-channel/src/channel.rs @@ -14,6 +14,7 @@ use crate::err::{ }; use crate::flavors; use crate::select::{Operation, SelectHandle, Token}; +use crate::utils;
/// Creates a channel of unbounded capacity. /// @@ -471,7 +472,7 @@ impl<T> Sender<T> { /// ); /// ``` pub fn send_timeout(&self, msg: T, timeout: Duration) -> Result<(), SendTimeoutError<T>> { - self.send_deadline(msg, Instant::now() + timeout) + self.send_deadline(msg, utils::convert_timeout_to_deadline(timeout)) }
/// Waits for a message to be sent into the channel, but only until a given deadline. @@ -861,7 +862,7 @@ impl<T> Receiver<T> { /// ); /// ``` pub fn recv_timeout(&self, timeout: Duration) -> Result<T, RecvTimeoutError> { - self.recv_deadline(Instant::now() + timeout) + self.recv_deadline(utils::convert_timeout_to_deadline(timeout)) }
/// Waits for a message to be received from the channel, but only before a given deadline. diff --git a/third_party/rust/crossbeam-channel/src/err.rs b/third_party/rust/crossbeam-channel/src/err.rs index 578acc69ac0e3..18cb8307a85b4 100644 --- a/third_party/rust/crossbeam-channel/src/err.rs +++ b/third_party/rust/crossbeam-channel/src/err.rs @@ -308,7 +308,6 @@ impl From<RecvError> for TryRecvError {
impl TryRecvError { /// Returns `true` if the receive operation failed because the channel is empty. - #[allow(clippy::trivially_copy_pass_by_ref)] pub fn is_empty(&self) -> bool { match self { TryRecvError::Empty => true, @@ -317,7 +316,6 @@ impl TryRecvError { }
/// Returns `true` if the receive operation failed because the channel is disconnected. - #[allow(clippy::trivially_copy_pass_by_ref)] pub fn is_disconnected(&self) -> bool { match self { TryRecvError::Disconnected => true, @@ -347,7 +345,6 @@ impl From<RecvError> for RecvTimeoutError {
impl RecvTimeoutError { /// Returns `true` if the receive operation timed out. - #[allow(clippy::trivially_copy_pass_by_ref)] pub fn is_timeout(&self) -> bool { match self { RecvTimeoutError::Timeout => true, @@ -356,7 +353,6 @@ impl RecvTimeoutError { }
/// Returns `true` if the receive operation failed because the channel is disconnected. - #[allow(clippy::trivially_copy_pass_by_ref)] pub fn is_disconnected(&self) -> bool { match self { RecvTimeoutError::Disconnected => true, diff --git a/third_party/rust/crossbeam-channel/src/flavors/array.rs b/third_party/rust/crossbeam-channel/src/flavors/array.rs index 871768ccd0cc3..c708a0442e72f 100644 --- a/third_party/rust/crossbeam-channel/src/flavors/array.rs +++ b/third_party/rust/crossbeam-channel/src/flavors/array.rs @@ -9,7 +9,6 @@ //! - https://docs.google.com/document/d/1yIAYmbvL3JxOKOjuCyon7JhW4cSv1wy5hC0ApeGMV9s/pub
use std::cell::UnsafeCell; -use std::marker::PhantomData; use std::mem::MaybeUninit; use std::ptr; use std::sync::atomic::{self, AtomicUsize, Ordering}; @@ -33,7 +32,7 @@ struct Slot<T> {
/// The token type for the array flavor. #[derive(Debug)] -pub struct ArrayToken { +pub(crate) struct ArrayToken { /// Slot to read from or write to. slot: *const u8,
@@ -72,7 +71,7 @@ pub(crate) struct Channel<T> { tail: CachePadded<AtomicUsize>,
/// The buffer holding slots. - buffer: *mut Slot<T>, + buffer: Box<[Slot<T>]>,
/// The channel capacity. cap: usize, @@ -88,9 +87,6 @@ pub(crate) struct Channel<T> {
/// Receivers waiting while the channel is empty and not disconnected. receivers: SyncWaker, - - /// Indicates that dropping a `Channel<T>` may drop values of type `T`. - _marker: PhantomData<T>, }
impl<T> Channel<T> { @@ -109,18 +105,15 @@ impl<T> Channel<T> {
// Allocate a buffer of `cap` slots initialized // with stamps. - let buffer = { - let boxed: Box<[Slot<T>]> = (0..cap) - .map(|i| { - // Set the stamp to `{ lap: 0, mark: 0, index: i }`. - Slot { - stamp: AtomicUsize::new(i), - msg: UnsafeCell::new(MaybeUninit::uninit()), - } - }) - .collect(); - Box::into_raw(boxed) as *mut Slot<T> - }; + let buffer: Box<[Slot<T>]> = (0..cap) + .map(|i| { + // Set the stamp to `{ lap: 0, mark: 0, index: i }`. + Slot { + stamp: AtomicUsize::new(i), + msg: UnsafeCell::new(MaybeUninit::uninit()), + } + }) + .collect();
Channel { buffer, @@ -131,7 +124,6 @@ impl<T> Channel<T> { tail: CachePadded::new(AtomicUsize::new(tail)), senders: SyncWaker::new(), receivers: SyncWaker::new(), - _marker: PhantomData, } }
@@ -163,7 +155,8 @@ impl<T> Channel<T> { let lap = tail & !(self.one_lap - 1);
// Inspect the corresponding slot. - let slot = unsafe { &*self.buffer.add(index) }; + debug_assert!(index < self.buffer.len()); + let slot = unsafe { self.buffer.get_unchecked(index) }; let stamp = slot.stamp.load(Ordering::Acquire);
// If the tail and the stamp match, we may attempt to push. @@ -245,7 +238,8 @@ impl<T> Channel<T> { let lap = head & !(self.one_lap - 1);
// Inspect the corresponding slot. - let slot = unsafe { &*self.buffer.add(index) }; + debug_assert!(index < self.buffer.len()); + let slot = unsafe { self.buffer.get_unchecked(index) }; let stamp = slot.stamp.load(Ordering::Acquire);
// If the the stamp is ahead of the head by 1, we may attempt to pop. @@ -475,7 +469,6 @@ impl<T> Channel<T> { }
/// Returns the capacity of the channel. - #[allow(clippy::unnecessary_wraps)] // This is intentional. pub(crate) fn capacity(&self) -> Option<usize> { Some(self.cap) } @@ -540,23 +533,12 @@ impl<T> Drop for Channel<T> { };
unsafe { - let p = { - let slot = &mut *self.buffer.add(index); - let msg = &mut *slot.msg.get(); - msg.as_mut_ptr() - }; - p.drop_in_place(); + debug_assert!(index < self.buffer.len()); + let slot = self.buffer.get_unchecked_mut(index); + let msg = &mut *slot.msg.get(); + msg.as_mut_ptr().drop_in_place(); } } - - // Finally, deallocate the buffer, but don't run any destructors. - unsafe { - // Create a slice from the buffer to make - // a fat pointer. Then, use Box::from_raw - // to deallocate it. - let ptr = std::slice::from_raw_parts_mut(self.buffer, self.cap) as *mut [Slot<T>]; - Box::from_raw(ptr); - } } }
diff --git a/third_party/rust/crossbeam-channel/src/flavors/at.rs b/third_party/rust/crossbeam-channel/src/flavors/at.rs index 4581edba1247a..ca5ee60f52dca 100644 --- a/third_party/rust/crossbeam-channel/src/flavors/at.rs +++ b/third_party/rust/crossbeam-channel/src/flavors/at.rs @@ -35,7 +35,7 @@ impl Channel { /// Creates a channel that delivers a message after a certain duration of time. #[inline] pub(crate) fn new_timeout(dur: Duration) -> Self { - Self::new_deadline(Instant::now() + dur) + Self::new_deadline(utils::convert_timeout_to_deadline(dur)) }
/// Attempts to receive a message without blocking. @@ -142,7 +142,6 @@ impl Channel { }
/// Returns the capacity of the channel. - #[allow(clippy::unnecessary_wraps)] // This is intentional. #[inline] pub(crate) fn capacity(&self) -> Option<usize> { Some(1) diff --git a/third_party/rust/crossbeam-channel/src/flavors/list.rs b/third_party/rust/crossbeam-channel/src/flavors/list.rs index 5056aa431326a..a0bcebb4be4bb 100644 --- a/third_party/rust/crossbeam-channel/src/flavors/list.rs +++ b/third_party/rust/crossbeam-channel/src/flavors/list.rs @@ -126,7 +126,7 @@ struct Position<T> {
/// The token type for the list flavor. #[derive(Debug)] -pub struct ListToken { +pub(crate) struct ListToken { /// The block of slots. block: *const u8,
diff --git a/third_party/rust/crossbeam-channel/src/flavors/never.rs b/third_party/rust/crossbeam-channel/src/flavors/never.rs index 1951e963faf8a..277a61dc1c567 100644 --- a/third_party/rust/crossbeam-channel/src/flavors/never.rs +++ b/third_party/rust/crossbeam-channel/src/flavors/never.rs @@ -65,7 +65,6 @@ impl<T> Channel<T> { }
/// Returns the capacity of the channel. - #[allow(clippy::unnecessary_wraps)] // This is intentional. #[inline] pub(crate) fn capacity(&self) -> Option<usize> { Some(0) diff --git a/third_party/rust/crossbeam-channel/src/flavors/tick.rs b/third_party/rust/crossbeam-channel/src/flavors/tick.rs index d4b1f6c78d49f..4201b6eb0b2ea 100644 --- a/third_party/rust/crossbeam-channel/src/flavors/tick.rs +++ b/third_party/rust/crossbeam-channel/src/flavors/tick.rs @@ -10,6 +10,7 @@ use crossbeam_utils::atomic::AtomicCell; use crate::context::Context; use crate::err::{RecvTimeoutError, TryRecvError}; use crate::select::{Operation, SelectHandle, Token}; +use crate::utils;
/// Result of a receive operation. pub(crate) type TickToken = Option<Instant>; @@ -28,7 +29,7 @@ impl Channel { #[inline] pub(crate) fn new(dur: Duration) -> Self { Channel { - delivery_time: AtomicCell::new(Instant::now() + dur), + delivery_time: AtomicCell::new(utils::convert_timeout_to_deadline(dur)), duration: dur, } } @@ -112,7 +113,6 @@ impl Channel { }
/// Returns the capacity of the channel. - #[allow(clippy::unnecessary_wraps)] // This is intentional. #[inline] pub(crate) fn capacity(&self) -> Option<usize> { Some(1) diff --git a/third_party/rust/crossbeam-channel/src/flavors/zero.rs b/third_party/rust/crossbeam-channel/src/flavors/zero.rs index 4afbd8f61a994..2208d12c14459 100644 --- a/third_party/rust/crossbeam-channel/src/flavors/zero.rs +++ b/third_party/rust/crossbeam-channel/src/flavors/zero.rs @@ -17,7 +17,7 @@ use crate::utils::Spinlock; use crate::waker::Waker;
/// A pointer to a packet. -pub struct ZeroToken(*mut ()); +pub(crate) struct ZeroToken(*mut ());
impl Default for ZeroToken { fn default() -> Self { @@ -363,7 +363,6 @@ impl<T> Channel<T> { }
/// Returns the capacity of the channel. - #[allow(clippy::unnecessary_wraps)] // This is intentional. pub(crate) fn capacity(&self) -> Option<usize> { Some(0) } diff --git a/third_party/rust/crossbeam-channel/src/select.rs b/third_party/rust/crossbeam-channel/src/select.rs index 6103ef4a4a3a8..710b612216b36 100644 --- a/third_party/rust/crossbeam-channel/src/select.rs +++ b/third_party/rust/crossbeam-channel/src/select.rs @@ -22,12 +22,13 @@ use crate::utils; // This is a private API that is used by the select macro. #[derive(Debug, Default)] pub struct Token { - pub at: flavors::at::AtToken, - pub array: flavors::array::ArrayToken, - pub list: flavors::list::ListToken, - pub never: flavors::never::NeverToken, - pub tick: flavors::tick::TickToken, - pub zero: flavors::zero::ZeroToken, + pub(crate) at: flavors::at::AtToken, + pub(crate) array: flavors::array::ArrayToken, + pub(crate) list: flavors::list::ListToken, + #[allow(dead_code)] + pub(crate) never: flavors::never::NeverToken, + pub(crate) tick: flavors::tick::TickToken, + pub(crate) zero: flavors::zero::ZeroToken, }
/// Identifier associated with an operation by a specific thread on a specific channel. @@ -486,7 +487,7 @@ pub fn select_timeout<'a>( handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], timeout: Duration, ) -> Result<SelectedOperation<'a>, SelectTimeoutError> { - select_deadline(handles, Instant::now() + timeout) + select_deadline(handles, utils::convert_timeout_to_deadline(timeout)) }
/// Blocks until a given deadline, or until one of the operations becomes ready and selects it. @@ -1042,7 +1043,7 @@ impl<'a> Select<'a> { /// } /// ``` pub fn ready_timeout(&mut self, timeout: Duration) -> Result<usize, ReadyTimeoutError> { - self.ready_deadline(Instant::now() + timeout) + self.ready_deadline(utils::convert_timeout_to_deadline(timeout)) }
/// Blocks until a given deadline, or until one of the operations becomes ready. diff --git a/third_party/rust/crossbeam-channel/src/select_macro.rs b/third_party/rust/crossbeam-channel/src/select_macro.rs index f8b247ea43c68..0a609573e1e8b 100644 --- a/third_party/rust/crossbeam-channel/src/select_macro.rs +++ b/third_party/rust/crossbeam-channel/src/select_macro.rs @@ -121,18 +121,7 @@ macro_rules! crossbeam_channel_internal { }; // Only one case remains. (@list - ($case:ident ($($args:tt)*) $(-> $res:pat)* => $body:expr) - ($($head:tt)*) - ) => { - $crate::crossbeam_channel_internal!( - @list - () - ($($head)* $case ($($args)*) $(-> $res)* => { $body },) - ) - }; - // Accept a trailing comma at the end of the list. - (@list - ($case:ident ($($args:tt)*) $(-> $res:pat)* => $body:expr,) + ($case:ident ($($args:tt)*) $(-> $res:pat)* => $body:expr $(,)?) ($($head:tt)*) ) => { $crate::crossbeam_channel_internal!( @@ -373,20 +362,7 @@ macro_rules! crossbeam_channel_internal {
// Check the format of a recv case. (@case - (recv($r:expr) -> $res:pat => $body:tt, $($tail:tt)*) - ($($cases:tt)*) - $default:tt - ) => { - $crate::crossbeam_channel_internal!( - @case - ($($tail)*) - ($($cases)* recv($r) -> $res => $body,) - $default - ) - }; - // Allow trailing comma... - (@case - (recv($r:expr,) -> $res:pat => $body:tt, $($tail:tt)*) + (recv($r:expr $(,)?) -> $res:pat => $body:tt, $($tail:tt)*) ($($cases:tt)*) $default:tt ) => { @@ -428,20 +404,7 @@ macro_rules! crossbeam_channel_internal {
// Check the format of a send case. (@case - (send($s:expr, $m:expr) -> $res:pat => $body:tt, $($tail:tt)*) - ($($cases:tt)*) - $default:tt - ) => { - $crate::crossbeam_channel_internal!( - @case - ($($tail)*) - ($($cases)* send($s, $m) -> $res => $body,) - $default - ) - }; - // Allow trailing comma... - (@case - (send($s:expr, $m:expr,) -> $res:pat => $body:tt, $($tail:tt)*) + (send($s:expr, $m:expr $(,)?) -> $res:pat => $body:tt, $($tail:tt)*) ($($cases:tt)*) $default:tt ) => { @@ -496,20 +459,7 @@ macro_rules! crossbeam_channel_internal { }; // Check the format of a default case with timeout. (@case - (default($timeout:expr) => $body:tt, $($tail:tt)*) - $cases:tt - () - ) => { - $crate::crossbeam_channel_internal!( - @case - ($($tail)*) - $cases - (default($timeout) => $body,) - ) - }; - // Allow trailing comma... - (@case - (default($timeout:expr,) => $body:tt, $($tail:tt)*) + (default($timeout:expr $(,)?) => $body:tt, $($tail:tt)*) $cases:tt () ) => { diff --git a/third_party/rust/crossbeam-channel/src/utils.rs b/third_party/rust/crossbeam-channel/src/utils.rs index 557b6a0d771d2..d87c2408c58b9 100644 --- a/third_party/rust/crossbeam-channel/src/utils.rs +++ b/third_party/rust/crossbeam-channel/src/utils.rs @@ -61,6 +61,14 @@ pub(crate) fn sleep_until(deadline: Option<Instant>) { } }
+// https://github.com/crossbeam-rs/crossbeam/issues/795 +pub(crate) fn convert_timeout_to_deadline(timeout: Duration) -> Instant { + match Instant::now().checked_add(timeout) { + Some(deadline) => deadline, + None => Instant::now() + Duration::from_secs(86400 * 365 * 30), + } +} + /// A simple spinlock. pub(crate) struct Spinlock<T> { flag: AtomicBool, diff --git a/third_party/rust/crossbeam-channel/src/waker.rs b/third_party/rust/crossbeam-channel/src/waker.rs index dec73a96fdf2f..ee445ec8c4eae 100644 --- a/third_party/rust/crossbeam-channel/src/waker.rs +++ b/third_party/rust/crossbeam-channel/src/waker.rs @@ -77,26 +77,32 @@ impl Waker { /// Attempts to find another thread's entry, select the operation, and wake it up. #[inline] pub(crate) fn try_select(&mut self) -> Option<Entry> { - self.selectors - .iter() - .position(|selector| { - // Does the entry belong to a different thread? - selector.cx.thread_id() != current_thread_id() - && selector // Try selecting this operation. - .cx - .try_select(Selected::Operation(selector.oper)) - .is_ok() - && { - // Provide the packet. - selector.cx.store_packet(selector.packet); - // Wake the thread up. - selector.cx.unpark(); - true - } - }) - // Remove the entry from the queue to keep it clean and improve - // performance. - .map(|pos| self.selectors.remove(pos)) + if self.selectors.is_empty() { + None + } else { + let thread_id = current_thread_id(); + + self.selectors + .iter() + .position(|selector| { + // Does the entry belong to a different thread? + selector.cx.thread_id() != thread_id + && selector // Try selecting this operation. + .cx + .try_select(Selected::Operation(selector.oper)) + .is_ok() + && { + // Provide the packet. + selector.cx.store_packet(selector.packet); + // Wake the thread up. + selector.cx.unpark(); + true + } + }) + // Remove the entry from the queue to keep it clean and improve + // performance. + .map(|pos| self.selectors.remove(pos)) + } }
/// Returns `true` if there is an entry which can be selected by the current thread. diff --git a/third_party/rust/crossbeam-channel/tests/array.rs b/third_party/rust/crossbeam-channel/tests/array.rs index bb2cebe882ada..7c4fc4dffc32d 100644 --- a/third_party/rust/crossbeam-channel/tests/array.rs +++ b/third_party/rust/crossbeam-channel/tests/array.rs @@ -1,7 +1,5 @@ //! Tests for the array channel flavor.
-#![cfg(not(miri))] // TODO: many assertions failed due to Miri is slow - use std::any::Any; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; @@ -254,7 +252,13 @@ fn recv_after_disconnect() {
#[test] fn len() { + #[cfg(miri)] + const COUNT: usize = 250; + #[cfg(not(miri))] const COUNT: usize = 25_000; + #[cfg(miri)] + const CAP: usize = 100; + #[cfg(not(miri))] const CAP: usize = 1000;
let (s, r) = bounded(CAP); @@ -347,6 +351,9 @@ fn disconnect_wakes_receiver() {
#[test] fn spsc() { + #[cfg(miri)] + const COUNT: usize = 100; + #[cfg(not(miri))] const COUNT: usize = 100_000;
let (s, r) = bounded(3); @@ -369,6 +376,9 @@ fn spsc() {
#[test] fn mpmc() { + #[cfg(miri)] + const COUNT: usize = 100; + #[cfg(not(miri))] const COUNT: usize = 25_000; const THREADS: usize = 4;
@@ -401,6 +411,9 @@ fn mpmc() {
#[test] fn stress_oneshot() { + #[cfg(miri)] + const COUNT: usize = 100; + #[cfg(not(miri))] const COUNT: usize = 10_000;
for _ in 0..COUNT { @@ -416,6 +429,9 @@ fn stress_oneshot() {
#[test] fn stress_iter() { + #[cfg(miri)] + const COUNT: usize = 100; + #[cfg(not(miri))] const COUNT: usize = 100_000;
let (request_s, request_r) = bounded(1); @@ -481,6 +497,7 @@ fn stress_timeout_two_threads() { .unwrap(); }
+#[cfg_attr(miri, ignore)] // Miri is too slow #[test] fn drops() { const RUNS: usize = 100; @@ -533,6 +550,9 @@ fn drops() {
#[test] fn linearizable() { + #[cfg(miri)] + const COUNT: usize = 100; + #[cfg(not(miri))] const COUNT: usize = 25_000; const THREADS: usize = 4;
@@ -553,6 +573,9 @@ fn linearizable() {
#[test] fn fairness() { + #[cfg(miri)] + const COUNT: usize = 100; + #[cfg(not(miri))] const COUNT: usize = 10_000;
let (s1, r1) = bounded::<()>(COUNT); @@ -575,6 +598,9 @@ fn fairness() {
#[test] fn fairness_duplicates() { + #[cfg(miri)] + const COUNT: usize = 100; + #[cfg(not(miri))] const COUNT: usize = 10_000;
let (s, r) = bounded::<()>(COUNT); @@ -619,6 +645,9 @@ fn recv_in_send() {
#[test] fn channel_through_channel() { + #[cfg(miri)] + const COUNT: usize = 100; + #[cfg(not(miri))] const COUNT: usize = 1000;
type T = Box<dyn Any + Send>; @@ -654,3 +683,56 @@ fn channel_through_channel() { }) .unwrap(); } + +#[test] +fn panic_on_drop() { + struct Msg1<'a>(&'a mut bool); + impl Drop for Msg1<'_> { + fn drop(&mut self) { + if *self.0 && !std::thread::panicking() { + panic!("double drop"); + } else { + *self.0 = true; + } + } + } + + struct Msg2<'a>(&'a mut bool); + impl Drop for Msg2<'_> { + fn drop(&mut self) { + if *self.0 { + panic!("double drop"); + } else { + *self.0 = true; + panic!("first drop"); + } + } + } + + // normal + let (s, r) = bounded(2); + let (mut a, mut b) = (false, false); + s.send(Msg1(&mut a)).unwrap(); + s.send(Msg1(&mut b)).unwrap(); + drop(s); + drop(r); + assert!(a); + assert!(b); + + // panic on drop + let (s, r) = bounded(2); + let (mut a, mut b) = (false, false); + s.send(Msg2(&mut a)).unwrap(); + s.send(Msg2(&mut b)).unwrap(); + drop(s); + let res = std::panic::catch_unwind(move || { + drop(r); + }); + assert_eq!( + *res.unwrap_err().downcast_ref::<&str>().unwrap(), + "first drop" + ); + assert!(a); + // Elements after the panicked element will leak. + assert!(!b); +} diff --git a/third_party/rust/crossbeam-channel/tests/select_macro.rs b/third_party/rust/crossbeam-channel/tests/select_macro.rs index 0b9a21a5c62cb..0c49cb8c59e1d 100644 --- a/third_party/rust/crossbeam-channel/tests/select_macro.rs +++ b/third_party/rust/crossbeam-channel/tests/select_macro.rs @@ -1468,3 +1468,14 @@ fn disconnect_wakes_receiver() { }) .unwrap(); } + +#[test] +fn trailing_comma() { + let (s, r) = unbounded::<usize>(); + + select! { + send(s, 1,) -> _ => {}, + recv(r,) -> _ => {}, + default(ms(1000),) => {}, + } +}