Skip to content

Commit

Permalink
channel: Add new_biased constructor for biased channel selection (#1150)
Browse files Browse the repository at this point in the history
  • Loading branch information
JabobKrauskopf authored and taiki-e committed Dec 15, 2024
1 parent d0d0a80 commit 66d41a9
Showing 1 changed file with 33 additions and 7 deletions.
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> {
Select {
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()
}
}

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 @@ -821,7 +846,7 @@ impl<'a> Select<'a> {
/// }
/// ```
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 @@ -871,7 +896,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 @@ -923,7 +948,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 @@ -962,7 +987,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 @@ -1015,7 +1040,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 @@ -1108,7 +1133,7 @@ impl<'a> Select<'a> {
/// }
/// ```
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 @@ -1120,6 +1145,7 @@ impl<'a> Clone for Select<'a> {
Select {
handles: self.handles.clone(),
next_index: self.next_index,
biased: self.biased,
}
}
}
Expand Down

0 comments on commit 66d41a9

Please sign in to comment.