Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add new_biased constructor for biased channel selection #1150

Merged
merged 2 commits into from
Dec 8, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 33 additions & 7 deletions crossbeam-channel/src/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,9 @@ pub struct Select<'a> {

/// The next index to assign to an operation.
next_index: usize,

/// Whether to use the index of handles as bias for selecting ready operations.
biased: bool,
}

unsafe impl Send for Select<'_> {}
Expand All @@ -633,6 +636,28 @@ impl<'a> Select<'a> {
Self {
handles: Vec::with_capacity(4),
next_index: 0,
biased: false,
}
}

/// Creates an empty list of channel operations with biased selection.
///
/// When multiple handles are ready, this will select the operation with the lowest index.
///
/// # Examples
///
/// ```
/// use crossbeam_channel::Select;
///
/// let mut sel = Select::new_biased();
///
/// // The list of operations is empty, which means no operation can be selected.
/// assert!(sel.try_select().is_err());
/// ```
pub fn new_biased() -> Self {
Self {
biased: true,
..Default::default()
JabobKrauskopf marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down Expand Up @@ -774,7 +799,7 @@ impl<'a> Select<'a> {
/// }
/// ```
pub fn try_select(&mut self) -> Result<SelectedOperation<'a>, TrySelectError> {
try_select(&mut self.handles, false)
try_select(&mut self.handles, self.biased)
}

/// Blocks until one of the operations becomes ready and selects it.
Expand Down Expand Up @@ -825,7 +850,7 @@ impl<'a> Select<'a> {
/// # t2.join().unwrap(); // join thread to avoid https://github.com/rust-lang/miri/issues/1371
/// ```
pub fn select(&mut self) -> SelectedOperation<'a> {
select(&mut self.handles, false)
select(&mut self.handles, self.biased)
}

/// Blocks for a limited time until one of the operations becomes ready and selects it.
Expand Down Expand Up @@ -879,7 +904,7 @@ impl<'a> Select<'a> {
&mut self,
timeout: Duration,
) -> Result<SelectedOperation<'a>, SelectTimeoutError> {
select_timeout(&mut self.handles, timeout, false)
select_timeout(&mut self.handles, timeout, self.biased)
}

/// Blocks until a given deadline, or until one of the operations becomes ready and selects it.
Expand Down Expand Up @@ -935,7 +960,7 @@ impl<'a> Select<'a> {
&mut self,
deadline: Instant,
) -> Result<SelectedOperation<'a>, SelectTimeoutError> {
select_deadline(&mut self.handles, deadline, false)
select_deadline(&mut self.handles, deadline, self.biased)
}

/// Attempts to find a ready operation without blocking.
Expand Down Expand Up @@ -974,7 +999,7 @@ impl<'a> Select<'a> {
/// }
/// ```
pub fn try_ready(&mut self) -> Result<usize, TryReadyError> {
match run_ready(&mut self.handles, Timeout::Now, false) {
match run_ready(&mut self.handles, Timeout::Now, self.biased) {
None => Err(TryReadyError),
Some(index) => Ok(index),
}
Expand Down Expand Up @@ -1031,7 +1056,7 @@ impl<'a> Select<'a> {
panic!("no operations have been added to `Select`");
}

run_ready(&mut self.handles, Timeout::Never, false).unwrap()
run_ready(&mut self.handles, Timeout::Never, self.biased).unwrap()
}

/// Blocks for a limited time until one of the operations becomes ready.
Expand Down Expand Up @@ -1132,7 +1157,7 @@ impl<'a> Select<'a> {
/// # t2.join().unwrap(); // join thread to avoid https://github.com/rust-lang/miri/issues/1371
/// ```
pub fn ready_deadline(&mut self, deadline: Instant) -> Result<usize, ReadyTimeoutError> {
match run_ready(&mut self.handles, Timeout::At(deadline), false) {
match run_ready(&mut self.handles, Timeout::At(deadline), self.biased) {
None => Err(ReadyTimeoutError),
Some(index) => Ok(index),
}
Expand All @@ -1144,6 +1169,7 @@ impl Clone for Select<'_> {
Self {
handles: self.handles.clone(),
next_index: self.next_index,
biased: self.biased,
}
}
}
Expand Down
Loading