diff options
| author | Ibraheem Ahmed <ibraheem@ibraheem.ca> | 2022-10-17 19:09:54 -0400 |
|---|---|---|
| committer | Ibraheem Ahmed <ibraheem@ibraheem.ca> | 2022-11-09 23:18:06 -0500 |
| commit | a43da5a09701469e013c623c7cfc1e2f7ec83e47 (patch) | |
| tree | 98571ae0b14396eb66f93c80bbaee632643449eb /library/std/src/sync/mpmc/select.rs | |
| parent | 34115d040b43d9a0dcc313c6282520a86d1e6f61 (diff) | |
| download | rust-a43da5a09701469e013c623c7cfc1e2f7ec83e47.tar.gz rust-a43da5a09701469e013c623c7cfc1e2f7ec83e47.zip | |
initial port of crossbeam-channel
Diffstat (limited to 'library/std/src/sync/mpmc/select.rs')
| -rw-r--r-- | library/std/src/sync/mpmc/select.rs | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/library/std/src/sync/mpmc/select.rs b/library/std/src/sync/mpmc/select.rs new file mode 100644 index 00000000000..56a83fee2e1 --- /dev/null +++ b/library/std/src/sync/mpmc/select.rs @@ -0,0 +1,71 @@ +/// Temporary data that gets initialized during a blocking operation, and is consumed by +/// `read` or `write`. +/// +/// Each field contains data associated with a specific channel flavor. +#[derive(Debug, Default)] +pub struct Token { + pub(crate) array: super::array::ArrayToken, + pub(crate) list: super::list::ListToken, + #[allow(dead_code)] + pub(crate) zero: super::zero::ZeroToken, +} + +/// Identifier associated with an operation by a specific thread on a specific channel. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct Operation(usize); + +impl Operation { + /// Creates an operation identifier from a mutable reference. + /// + /// This function essentially just turns the address of the reference into a number. The + /// reference should point to a variable that is specific to the thread and the operation, + /// and is alive for the entire duration of a blocking operation. + #[inline] + pub fn hook<T>(r: &mut T) -> Operation { + let val = r as *mut T as usize; + // Make sure that the pointer address doesn't equal the numerical representation of + // `Selected::{Waiting, Aborted, Disconnected}`. + assert!(val > 2); + Operation(val) + } +} + +/// Current state of a blocking operation. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Selected { + /// Still waiting for an operation. + Waiting, + + /// The attempt to block the current thread has been aborted. + Aborted, + + /// An operation became ready because a channel is disconnected. + Disconnected, + + /// An operation became ready because a message can be sent or received. + Operation(Operation), +} + +impl From<usize> for Selected { + #[inline] + fn from(val: usize) -> Selected { + match val { + 0 => Selected::Waiting, + 1 => Selected::Aborted, + 2 => Selected::Disconnected, + oper => Selected::Operation(Operation(oper)), + } + } +} + +impl Into<usize> for Selected { + #[inline] + fn into(self) -> usize { + match self { + Selected::Waiting => 0, + Selected::Aborted => 1, + Selected::Disconnected => 2, + Selected::Operation(Operation(val)) => val, + } + } +} |
