crossbeam-channel/src/select.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! Interface to the select mechanism. |
2 | | |
3 | | use std::fmt; |
4 | | use std::marker::PhantomData; |
5 | | use std::mem; |
6 | | use std::time::{Duration, Instant}; |
7 | | |
8 | | use crossbeam_utils::Backoff; |
9 | | |
10 | | use crate::channel::{self, Receiver, Sender}; |
11 | | use crate::context::Context; |
12 | | use crate::err::{ReadyTimeoutError, TryReadyError}; |
13 | | use crate::err::{RecvError, SendError}; |
14 | | use crate::err::{SelectTimeoutError, TrySelectError}; |
15 | | use crate::flavors; |
16 | | use crate::utils; |
17 | | |
18 | | /// Temporary data that gets initialized during select or a blocking operation, and is consumed by |
19 | | /// `read` or `write`. |
20 | | /// |
21 | | /// Each field contains data associated with a specific channel flavor. |
22 | 88.1M | #[derive(Debug, Default)] <crossbeam_channel::select::Token as core::default::Default>::default Line | Count | Source | 22 | 724k | #[derive(Debug, Default)] |
<crossbeam_channel::select::Token as core::default::Default>::default Line | Count | Source | 22 | 9.91M | #[derive(Debug, Default)] |
<crossbeam_channel::select::Token as core::default::Default>::default Line | Count | Source | 22 | 5.38M | #[derive(Debug, Default)] |
<crossbeam_channel::select::Token as core::default::Default>::default Line | Count | Source | 22 | 275k | #[derive(Debug, Default)] |
<crossbeam_channel::select::Token as core::default::Default>::default Line | Count | Source | 22 | 1.57M | #[derive(Debug, Default)] |
<crossbeam_channel::select::Token as core::default::Default>::default Line | Count | Source | 22 | 126 | #[derive(Debug, Default)] |
<crossbeam_channel::select::Token as core::default::Default>::default Line | Count | Source | 22 | 3 | #[derive(Debug, Default)] |
<crossbeam_channel::select::Token as core::default::Default>::default Line | Count | Source | 22 | 1.53M | #[derive(Debug, Default)] |
<crossbeam_channel::select::Token as core::default::Default>::default Line | Count | Source | 22 | 1.48M | #[derive(Debug, Default)] |
<crossbeam_channel::select::Token as core::default::Default>::default Line | Count | Source | 22 | 66.9M | #[derive(Debug, Default)] |
<crossbeam_channel::select::Token as core::default::Default>::default Line | Count | Source | 22 | 287k | #[derive(Debug, Default)] |
|
23 | | pub struct Token { |
24 | | pub at: flavors::at::AtToken, |
25 | | pub array: flavors::array::ArrayToken, |
26 | | pub list: flavors::list::ListToken, |
27 | | pub never: flavors::never::NeverToken, |
28 | | pub tick: flavors::tick::TickToken, |
29 | | pub zero: flavors::zero::ZeroToken, |
30 | | } |
31 | | |
32 | | /// Identifier associated with an operation by a specific thread on a specific channel. |
33 | 8.62M | #[derive(Debug, C0 lone, Copy, PartialEq, E0 q)] <crossbeam_channel::select::Operation as core::cmp::PartialEq>::eq Line | Count | Source | 33 | 51.5k | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
<crossbeam_channel::select::Operation as core::cmp::PartialEq>::eq Line | Count | Source | 33 | 74.9k | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
<crossbeam_channel::select::Operation as core::cmp::PartialEq>::eq Line | Count | Source | 33 | 5.15M | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
<crossbeam_channel::select::Operation as core::cmp::PartialEq>::eq Line | Count | Source | 33 | 10.2k | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
<crossbeam_channel::select::Operation as core::cmp::PartialEq>::eq Line | Count | Source | 33 | 577 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
<crossbeam_channel::select::Operation as core::cmp::PartialEq>::eq Line | Count | Source | 33 | 1.54k | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
<crossbeam_channel::select::Operation as core::cmp::PartialEq>::eq Line | Count | Source | 33 | 60.5k | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
<crossbeam_channel::select::Operation as core::cmp::PartialEq>::eq Line | Count | Source | 33 | 3.27M | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
<crossbeam_channel::select::Operation as core::cmp::PartialEq>::ne Line | Count | Source | 33 | 19 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
<crossbeam_channel::select::Operation as core::cmp::PartialEq>::eq Line | Count | Source | 33 | 1 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
|
34 | | pub struct Operation(usize); |
35 | | |
36 | | impl Operation { |
37 | | /// Creates an operation identifier from a mutable reference. |
38 | | /// |
39 | | /// This function essentially just turns the address of the reference into a number. The |
40 | | /// reference should point to a variable that is specific to the thread and the operation, |
41 | | /// and is alive for the entire duration of select or blocking operation. |
42 | | #[inline] |
43 | 19.4M | pub fn hook<T>(r: &mut T) -> Operation { |
44 | 19.4M | let val = r as *mut T as usize; |
45 | | // Make sure that the pointer address doesn't equal the numerical representation of |
46 | | // `Selected::{Waiting, Aborted, Disconnected}`. |
47 | 19.4M | assert!(val > 2); |
48 | 19.4M | Operation(val) |
49 | 19.4M | } <crossbeam_channel::select::Operation>::hook::<crossbeam_channel::select::Token> Line | Count | Source | 43 | 374k | pub fn hook<T>(r: &mut T) -> Operation { | 44 | 374k | let val = r as *mut T as usize; | 45 | | // Make sure that the pointer address doesn't equal the numerical representation of | 46 | | // `Selected::{Waiting, Aborted, Disconnected}`. | 47 | 374k | assert!(val > 2); | 48 | 374k | Operation(val) | 49 | 374k | } |
<crossbeam_channel::select::Operation>::hook::<&dyn crossbeam_channel::select::SelectHandle> Line | Count | Source | 43 | 17.1M | pub fn hook<T>(r: &mut T) -> Operation { | 44 | 17.1M | let val = r as *mut T as usize; | 45 | | // Make sure that the pointer address doesn't equal the numerical representation of | 46 | | // `Selected::{Waiting, Aborted, Disconnected}`. | 47 | 17.1M | assert!(val > 2); | 48 | 17.1M | Operation(val) | 49 | 17.1M | } |
<crossbeam_channel::select::Operation>::hook::<crossbeam_channel::select::Token> Line | Count | Source | 43 | 855k | pub fn hook<T>(r: &mut T) -> Operation { | 44 | 855k | let val = r as *mut T as usize; | 45 | | // Make sure that the pointer address doesn't equal the numerical representation of | 46 | | // `Selected::{Waiting, Aborted, Disconnected}`. | 47 | 855k | assert!(val > 2); | 48 | 855k | Operation(val) | 49 | 855k | } |
<crossbeam_channel::select::Operation>::hook::<crossbeam_channel::select::Token> Line | Count | Source | 43 | 34.8k | pub fn hook<T>(r: &mut T) -> Operation { | 44 | 34.8k | let val = r as *mut T as usize; | 45 | | // Make sure that the pointer address doesn't equal the numerical representation of | 46 | | // `Selected::{Waiting, Aborted, Disconnected}`. | 47 | 34.8k | assert!(val > 2); | 48 | 34.8k | Operation(val) | 49 | 34.8k | } |
Unexecuted instantiation: <crossbeam_channel::select::Operation>::hook::<crossbeam_channel::select::Token> <crossbeam_channel::select::Operation>::hook::<crossbeam_channel::select::Token> Line | Count | Source | 43 | 697 | pub fn hook<T>(r: &mut T) -> Operation { | 44 | 697 | let val = r as *mut T as usize; | 45 | | // Make sure that the pointer address doesn't equal the numerical representation of | 46 | | // `Selected::{Waiting, Aborted, Disconnected}`. | 47 | 697 | assert!(val > 2); | 48 | 697 | Operation(val) | 49 | 697 | } |
<crossbeam_channel::select::Operation>::hook::<crossbeam_channel::select::Token> Line | Count | Source | 43 | 2 | pub fn hook<T>(r: &mut T) -> Operation { | 44 | 2 | let val = r as *mut T as usize; | 45 | | // Make sure that the pointer address doesn't equal the numerical representation of | 46 | | // `Selected::{Waiting, Aborted, Disconnected}`. | 47 | 2 | assert!(val > 2); | 48 | 2 | Operation(val) | 49 | 2 | } |
Unexecuted instantiation: <crossbeam_channel::select::Operation>::hook::<crossbeam_channel::select::Token> Unexecuted instantiation: <crossbeam_channel::select::Operation>::hook::<crossbeam_channel::select::Token> Unexecuted instantiation: <crossbeam_channel::select::Operation>::hook::<crossbeam_channel::select::Token> <crossbeam_channel::select::Operation>::hook::<crossbeam_channel::select::Token> Line | Count | Source | 43 | 1.83k | pub fn hook<T>(r: &mut T) -> Operation { | 44 | 1.83k | let val = r as *mut T as usize; | 45 | | // Make sure that the pointer address doesn't equal the numerical representation of | 46 | | // `Selected::{Waiting, Aborted, Disconnected}`. | 47 | 1.83k | assert!(val > 2); | 48 | 1.83k | Operation(val) | 49 | 1.83k | } |
<crossbeam_channel::select::Operation>::hook::<crossbeam_channel::select::Token> Line | Count | Source | 43 | 89.8k | pub fn hook<T>(r: &mut T) -> Operation { | 44 | 89.8k | let val = r as *mut T as usize; | 45 | | // Make sure that the pointer address doesn't equal the numerical representation of | 46 | | // `Selected::{Waiting, Aborted, Disconnected}`. | 47 | 89.8k | assert!(val > 2); | 48 | 89.8k | Operation(val) | 49 | 89.8k | } |
<crossbeam_channel::select::Operation>::hook::<crossbeam_channel::select::Token> Line | Count | Source | 43 | 835k | pub fn hook<T>(r: &mut T) -> Operation { | 44 | 835k | let val = r as *mut T as usize; | 45 | | // Make sure that the pointer address doesn't equal the numerical representation of | 46 | | // `Selected::{Waiting, Aborted, Disconnected}`. | 47 | 835k | assert!(val > 2); | 48 | 835k | Operation(val) | 49 | 835k | } |
<crossbeam_channel::select::Operation>::hook::<crossbeam_channel::select::Token> Line | Count | Source | 43 | 59.0k | pub fn hook<T>(r: &mut T) -> Operation { | 44 | 59.0k | let val = r as *mut T as usize; | 45 | | // Make sure that the pointer address doesn't equal the numerical representation of | 46 | | // `Selected::{Waiting, Aborted, Disconnected}`. | 47 | 59.0k | assert!(val > 2); | 48 | 59.0k | Operation(val) | 49 | 59.0k | } |
|
50 | | } |
51 | | |
52 | | /// Current state of a select or a blocking operation. |
53 | 25.2M | #[derive(Debug, C0 lone, Copy, P25.1M artialEq, E0 q)] <crossbeam_channel::select::Selected as core::cmp::PartialEq>::eq Line | Count | Source | 53 | 13.1k | #[derive(Debug, Clone, Copy, P13.1k artialEq, Eq)] |
<crossbeam_channel::select::Selected as core::cmp::PartialEq>::ne Line | Count | Source | 53 | 1.33M | #[derive(Debug, Clone, Copy, P1.31M artialEq, Eq)] |
<crossbeam_channel::select::Selected as core::cmp::PartialEq>::ne Line | Count | Source | 53 | 8.88M | #[derive(Debug, Clone, Copy, P8.88M artialEq, Eq)] |
<crossbeam_channel::select::Selected as core::cmp::PartialEq>::eq Line | Count | Source | 53 | 8.58M | #[derive(Debug, Clone, Copy, P8.58M artialEq, Eq)] |
<crossbeam_channel::select::Selected as core::cmp::PartialEq>::ne Line | Count | Source | 53 | 2.78M | #[derive(Debug, Clone, Copy, P2.74M artialEq, Eq)] |
<crossbeam_channel::select::Selected as core::cmp::PartialEq>::eq Line | Count | Source | 53 | 3.08k | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
<crossbeam_channel::select::Selected as core::cmp::PartialEq>::eq Line | Count | Source | 53 | 1 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
<crossbeam_channel::select::Selected as core::cmp::PartialEq>::ne Line | Count | Source | 53 | 129k | #[derive(Debug, Clone, Copy, P126k artialEq, Eq)] |
<crossbeam_channel::select::Selected as core::cmp::PartialEq>::ne Line | Count | Source | 53 | 1.61k | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
<crossbeam_channel::select::Selected as core::cmp::PartialEq>::ne Line | Count | Source | 53 | 24 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
<crossbeam_channel::select::Selected as core::cmp::PartialEq>::ne Line | Count | Source | 53 | 3.79k | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
<crossbeam_channel::select::Selected as core::cmp::PartialEq>::eq Line | Count | Source | 53 | 12.9k | #[derive(Debug, Clone, Copy, PartialEq12.9k , Eq)] |
<crossbeam_channel::select::Selected as core::cmp::PartialEq>::ne Line | Count | Source | 53 | 463k | #[derive(Debug, Clone, Copy, P461k artialEq, Eq)] |
<crossbeam_channel::select::Selected as core::cmp::PartialEq>::eq Line | Count | Source | 53 | 3.73k | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
<crossbeam_channel::select::Selected as core::cmp::PartialEq>::ne Line | Count | Source | 53 | 2.77M | #[derive(Debug, Clone, Copy, P2.74M artialEq, Eq)] |
<crossbeam_channel::select::Selected as core::cmp::PartialEq>::ne Line | Count | Source | 53 | 235k | #[derive(Debug, Clone, Copy, P231k artialEq, Eq)] |
<crossbeam_channel::select::Selected as core::cmp::PartialEq>::eq Line | Count | Source | 53 | 55.9k | #[derive(Debug, Clone, Copy, PartialEq55.8k , Eq)] |
|
54 | | pub enum Selected { |
55 | | /// Still waiting for an operation. |
56 | | Waiting, |
57 | | |
58 | | /// The attempt to block the current thread has been aborted. |
59 | | Aborted, |
60 | | |
61 | | /// An operation became ready because a channel is disconnected. |
62 | | Disconnected, |
63 | | |
64 | | /// An operation became ready because a message can be sent or received. |
65 | | Operation(Operation), |
66 | | } |
67 | | |
68 | | impl From<usize> for Selected { |
69 | | #[inline] |
70 | 16.6M | fn from(val: usize) -> Selected { |
71 | 16.6M | match val { |
72 | 5.90M | 0 => Selected::Waiting, |
73 | 8.42M | 1 => Selected::Aborted, |
74 | 26 | 2 => Selected::Disconnected, |
75 | 2.32M | oper => Selected::Operation(Operation(oper)), |
76 | | } |
77 | 16.6M | } <crossbeam_channel::select::Selected as core::convert::From<usize>>::from Line | Count | Source | 70 | 1.35M | fn from(val: usize) -> Selected { | 71 | 1.35M | match val { | 72 | 973k | 0 => Selected::Waiting, | 73 | 2.41k | 1 => Selected::Aborted, | 74 | 5 | 2 => Selected::Disconnected, | 75 | 377k | oper => Selected::Operation(Operation(oper)), | 76 | | } | 77 | 1.35M | } |
<crossbeam_channel::select::Selected as core::convert::From<usize>>::from Line | Count | Source | 70 | 8.89M | fn from(val: usize) -> Selected { | 71 | 8.89M | match val { | 72 | 409k | 0 => Selected::Waiting, | 73 | 8.41M | 1 => Selected::Aborted, | 74 | 5 | 2 => Selected::Disconnected, | 75 | 78.1k | oper => Selected::Operation(Operation(oper)), | 76 | | } | 77 | 8.89M | } |
<crossbeam_channel::select::Selected as core::convert::From<usize>>::from Line | Count | Source | 70 | 2.75M | fn from(val: usize) -> Selected { | 71 | 2.75M | match val { | 72 | 1.89M | 0 => Selected::Waiting, | 73 | 4 | 1 => Selected::Aborted, | 74 | 0 | 2 => Selected::Disconnected, | 75 | 856k | oper => Selected::Operation(Operation(oper)), | 76 | | } | 77 | 2.75M | } |
<crossbeam_channel::select::Selected as core::convert::From<usize>>::from Line | Count | Source | 70 | 130k | fn from(val: usize) -> Selected { | 71 | 130k | match val { | 72 | 94.8k | 0 => Selected::Waiting, | 73 | 1 | 1 => Selected::Aborted, | 74 | 6 | 2 => Selected::Disconnected, | 75 | 35.4k | oper => Selected::Operation(Operation(oper)), | 76 | | } | 77 | 130k | } |
Unexecuted instantiation: <crossbeam_channel::select::Selected as core::convert::From<usize>>::from <crossbeam_channel::select::Selected as core::convert::From<usize>>::from Line | Count | Source | 70 | 1.61k | fn from(val: usize) -> Selected { | 71 | 1.61k | match val { | 72 | 923 | 0 => Selected::Waiting, | 73 | 571 | 1 => Selected::Aborted, | 74 | 2 | 2 => Selected::Disconnected, | 75 | 121 | oper => Selected::Operation(Operation(oper)), | 76 | | } | 77 | 1.61k | } |
<crossbeam_channel::select::Selected as core::convert::From<usize>>::from Line | Count | Source | 70 | 24 | fn from(val: usize) -> Selected { | 71 | 24 | match val { | 72 | 22 | 0 => Selected::Waiting, | 73 | 0 | 1 => Selected::Aborted, | 74 | 0 | 2 => Selected::Disconnected, | 75 | 2 | oper => Selected::Operation(Operation(oper)), | 76 | | } | 77 | 24 | } |
Unexecuted instantiation: <crossbeam_channel::select::Selected as core::convert::From<usize>>::from Unexecuted instantiation: <crossbeam_channel::select::Selected as core::convert::From<usize>>::from Unexecuted instantiation: <crossbeam_channel::select::Selected as core::convert::From<usize>>::from Unexecuted instantiation: <crossbeam_channel::select::Selected as core::convert::From<usize>>::from <crossbeam_channel::select::Selected as core::convert::From<usize>>::from Line | Count | Source | 70 | 3.79k | fn from(val: usize) -> Selected { | 71 | 3.79k | match val { | 72 | 1.95k | 0 => Selected::Waiting, | 73 | 1.54k | 1 => Selected::Aborted, | 74 | 1 | 2 => Selected::Disconnected, | 75 | 291 | oper => Selected::Operation(Operation(oper)), | 76 | | } | 77 | 3.79k | } |
<crossbeam_channel::select::Selected as core::convert::From<usize>>::from Line | Count | Source | 70 | 477k | fn from(val: usize) -> Selected { | 71 | 477k | match val { | 72 | 383k | 0 => Selected::Waiting, | 73 | 10.7k | 1 => Selected::Aborted, | 74 | 5 | 2 => Selected::Disconnected, | 75 | 82.9k | oper => Selected::Operation(Operation(oper)), | 76 | | } | 77 | 477k | } |
<crossbeam_channel::select::Selected as core::convert::From<usize>>::from Line | Count | Source | 70 | 2.75M | fn from(val: usize) -> Selected { | 71 | 2.75M | match val { | 72 | 1.91M | 0 => Selected::Waiting, | 73 | 11 | 1 => Selected::Aborted, | 74 | 2 | 2 => Selected::Disconnected, | 75 | 838k | oper => Selected::Operation(Operation(oper)), | 76 | | } | 77 | 2.75M | } |
<crossbeam_channel::select::Selected as core::convert::From<usize>>::from Line | Count | Source | 70 | 282k | fn from(val: usize) -> Selected { | 71 | 282k | match val { | 72 | 222k | 0 => Selected::Waiting, | 73 | 0 | 1 => Selected::Aborted, | 74 | 0 | 2 => Selected::Disconnected, | 75 | 59.4k | oper => Selected::Operation(Operation(oper)), | 76 | | } | 77 | 282k | } |
|
78 | | } |
79 | | |
80 | | impl Into<usize> for Selected { |
81 | | #[inline] |
82 | 32.1M | fn into(self) -> usize { |
83 | 32.1M | match self { |
84 | 32.1M | Selected::Waiting => 021.3M , |
85 | 8.45M | Selected::Aborted => 1, |
86 | 360 | Selected::Disconnected => 2, |
87 | 2.33M | Selected::Operation(Operation(val)) => val, |
88 | | } |
89 | 32.1M | } <crossbeam_channel::select::Selected as core::convert::Into<usize>>::into Line | Count | Source | 82 | 1.14M | fn into(self) -> usize { | 83 | 1.14M | match self { | 84 | 1.14M | Selected::Waiting => 0744k , | 85 | 409 | Selected::Aborted => 1, | 86 | 5 | Selected::Disconnected => 2, | 87 | 397k | Selected::Operation(Operation(val)) => val, | 88 | | } | 89 | 1.14M | } |
<crossbeam_channel::select::Selected as core::convert::Into<usize>>::into Line | Count | Source | 82 | 25.3M | fn into(self) -> usize { | 83 | 25.3M | match self { | 84 | 25.3M | Selected::Waiting => 016.9M , | 85 | 8.44M | Selected::Aborted => 1, | 86 | 0 | Selected::Disconnected => 2, | 87 | 6 | Selected::Operation(Operation(val)) => val, | 88 | | } | 89 | 25.3M | } |
<crossbeam_channel::select::Selected as core::convert::Into<usize>>::into Line | Count | Source | 82 | 2.53M | fn into(self) -> usize { | 83 | 2.53M | match self { | 84 | 2.53M | Selected::Waiting => 01.67M , | 85 | 0 | Selected::Aborted => 1, | 86 | 334 | Selected::Disconnected => 2, | 87 | 860k | Selected::Operation(Operation(val)) => val, | 88 | | } | 89 | 2.53M | } |
<crossbeam_channel::select::Selected as core::convert::Into<usize>>::into Line | Count | Source | 82 | 107k | fn into(self) -> usize { | 83 | 107k | match self { | 84 | 107k | Selected::Waiting => 069.9k , | 85 | 98 | Selected::Aborted => 1, | 86 | 7 | Selected::Disconnected => 2, | 87 | 37.6k | Selected::Operation(Operation(val)) => val, | 88 | | } | 89 | 107k | } |
Unexecuted instantiation: <crossbeam_channel::select::Selected as core::convert::Into<usize>>::into <crossbeam_channel::select::Selected as core::convert::Into<usize>>::into Line | Count | Source | 82 | 2.40k | fn into(self) -> usize { | 83 | 2.40k | match self { | 84 | 2.40k | Selected::Waiting => 01.55k , | 85 | 574 | Selected::Aborted => 1, | 86 | 2 | Selected::Disconnected => 2, | 87 | 280 | Selected::Operation(Operation(val)) => val, | 88 | | } | 89 | 2.40k | } |
<crossbeam_channel::select::Selected as core::convert::Into<usize>>::into Line | Count | Source | 82 | 6 | fn into(self) -> usize { | 83 | 6 | match self { | 84 | 6 | Selected::Waiting => 04 , | 85 | 0 | Selected::Aborted => 1, | 86 | 0 | Selected::Disconnected => 2, | 87 | 2 | Selected::Operation(Operation(val)) => val, | 88 | | } | 89 | 6 | } |
Unexecuted instantiation: <crossbeam_channel::select::Selected as core::convert::Into<usize>>::into Unexecuted instantiation: <crossbeam_channel::select::Selected as core::convert::Into<usize>>::into Unexecuted instantiation: <crossbeam_channel::select::Selected as core::convert::Into<usize>>::into Unexecuted instantiation: <crossbeam_channel::select::Selected as core::convert::Into<usize>>::into Unexecuted instantiation: <crossbeam_channel::select::Selected as core::convert::Into<usize>>::into <crossbeam_channel::select::Selected as core::convert::Into<usize>>::into Line | Count | Source | 82 | 6.11k | fn into(self) -> usize { | 83 | 6.11k | match self { | 84 | 6.11k | Selected::Waiting => 03.97k , | 85 | 1.54k | Selected::Aborted => 1, | 86 | 1 | Selected::Disconnected => 2, | 87 | 590 | Selected::Operation(Operation(val)) => val, | 88 | | } | 89 | 6.11k | } |
<crossbeam_channel::select::Selected as core::convert::Into<usize>>::into Line | Count | Source | 82 | 343k | fn into(self) -> usize { | 83 | 343k | match self { | 84 | 343k | Selected::Waiting => 0216k , | 85 | 7.71k | Selected::Aborted => 1, | 86 | 6 | Selected::Disconnected => 2, | 87 | 119k | Selected::Operation(Operation(val)) => val, | 88 | | } | 89 | 343k | } |
<crossbeam_channel::select::Selected as core::convert::Into<usize>>::into Line | Count | Source | 82 | 2.45M | fn into(self) -> usize { | 83 | 2.45M | match self { | 84 | 2.45M | Selected::Waiting => 01.61M , | 85 | 4 | Selected::Aborted => 1, | 86 | 5 | Selected::Disconnected => 2, | 87 | 839k | Selected::Operation(Operation(val)) => val, | 88 | | } | 89 | 2.45M | } |
<crossbeam_channel::select::Selected as core::convert::Into<usize>>::into Line | Count | Source | 82 | 206k | fn into(self) -> usize { | 83 | 206k | match self { | 84 | 206k | Selected::Waiting => 0130k , | 85 | 0 | Selected::Aborted => 1, | 86 | 0 | Selected::Disconnected => 2, | 87 | 75.2k | Selected::Operation(Operation(val)) => val, | 88 | | } | 89 | 206k | } |
Unexecuted instantiation: <crossbeam_channel::select::Selected as core::convert::Into<usize>>::into |
90 | | } |
91 | | |
92 | | /// A receiver or a sender that can participate in select. |
93 | | /// |
94 | | /// This is a handle that assists select in executing an operation, registration, deciding on the |
95 | | /// appropriate deadline for blocking, etc. |
96 | | pub trait SelectHandle { |
97 | | /// Attempts to select an operation and returns `true` on success. |
98 | | fn try_select(&self, token: &mut Token) -> bool; |
99 | | |
100 | | /// Returns a deadline for an operation, if there is one. |
101 | | fn deadline(&self) -> Option<Instant>; |
102 | | |
103 | | /// Registers an operation for execution and returns `true` if it is now ready. |
104 | | fn register(&self, oper: Operation, cx: &Context) -> bool; |
105 | | |
106 | | /// Unregisters an operation for execution. |
107 | | fn unregister(&self, oper: Operation); |
108 | | |
109 | | /// Attempts to select an operation the thread got woken up for and returns `true` on success. |
110 | | fn accept(&self, token: &mut Token, cx: &Context) -> bool; |
111 | | |
112 | | /// Returns `true` if an operation can be executed without blocking. |
113 | | fn is_ready(&self) -> bool; |
114 | | |
115 | | /// Registers an operation for readiness notification and returns `true` if it is now ready. |
116 | | fn watch(&self, oper: Operation, cx: &Context) -> bool; |
117 | | |
118 | | /// Unregisters an operation for readiness notification. |
119 | | fn unwatch(&self, oper: Operation); |
120 | | } |
121 | | |
122 | | impl<T: SelectHandle> SelectHandle for &T { |
123 | 0 | fn try_select(&self, token: &mut Token) -> bool { |
124 | 0 | (**self).try_select(token) |
125 | 0 | } |
126 | | |
127 | 0 | fn deadline(&self) -> Option<Instant> { |
128 | 0 | (**self).deadline() |
129 | 0 | } |
130 | | |
131 | 0 | fn register(&self, oper: Operation, cx: &Context) -> bool { |
132 | 0 | (**self).register(oper, cx) |
133 | 0 | } |
134 | | |
135 | 0 | fn unregister(&self, oper: Operation) { |
136 | 0 | (**self).unregister(oper); |
137 | 0 | } |
138 | | |
139 | 0 | fn accept(&self, token: &mut Token, cx: &Context) -> bool { |
140 | 0 | (**self).accept(token, cx) |
141 | 0 | } |
142 | | |
143 | 0 | fn is_ready(&self) -> bool { |
144 | 0 | (**self).is_ready() |
145 | 0 | } |
146 | | |
147 | 0 | fn watch(&self, oper: Operation, cx: &Context) -> bool { |
148 | 0 | (**self).watch(oper, cx) |
149 | 0 | } |
150 | | |
151 | 0 | fn unwatch(&self, oper: Operation) { |
152 | 0 | (**self).unwatch(oper) |
153 | 0 | } |
154 | | } |
155 | | |
156 | | /// Determines when a select operation should time out. |
157 | 0 | #[derive(Clone, Copy, Eq, PartialEq)] |
158 | | enum Timeout { |
159 | | /// No blocking. |
160 | | Now, |
161 | | |
162 | | /// Block forever. |
163 | | Never, |
164 | | |
165 | | /// Time out after the time instant. |
166 | | At(Instant), |
167 | | } |
168 | | |
169 | | /// Runs until one of the operations is selected, potentially blocking the current thread. |
170 | | /// |
171 | | /// Successful receive operations will have to be followed up by `channel::read()` and successful |
172 | | /// send operations by `channel::write()`. |
173 | 9.92M | fn run_select( |
174 | 9.92M | handles: &mut [(&dyn SelectHandle, usize, *const u8)], |
175 | 9.92M | timeout: Timeout, |
176 | 9.92M | ) -> Option<(Token, usize, *const u8)> { |
177 | 9.92M | if handles.is_empty() { |
178 | | // Wait until the timeout and return. |
179 | 11 | match timeout { |
180 | 11 | Timeout::Now => return None7 , |
181 | | Timeout::Never => { |
182 | 0 | utils::sleep_until(None); |
183 | 0 | unreachable!(); |
184 | | } |
185 | 4 | Timeout::At(when) => { |
186 | 4 | utils::sleep_until(Some(when)); |
187 | 4 | return None; |
188 | | } |
189 | | } |
190 | 9.92M | } |
191 | 9.92M | |
192 | 9.92M | // Shuffle the operations for fairness. |
193 | 9.92M | utils::shuffle(handles); |
194 | 9.92M | |
195 | 9.92M | // Create a token, which serves as a temporary variable that gets initialized in this function |
196 | 9.92M | // and is later used by a call to `channel::read()` or `channel::write()` that completes the |
197 | 9.92M | // selected operation. |
198 | 9.92M | let mut token = Token::default(); |
199 | | |
200 | | // Try selecting one of the operations without blocking. |
201 | 10.7M | for &(handle, i, ptr) in handles9.92M .iter() { |
202 | 10.7M | if handle.try_select(&mut token) { |
203 | 1.43M | return Some((token, i, ptr)); |
204 | 9.31M | } |
205 | | } |
206 | | |
207 | 8.51M | loop { |
208 | 8.51M | // Prepare for blocking. |
209 | 8.52M | let res = Context::with(|cx| { |
210 | 8.52M | let mut sel = Selected::Waiting; |
211 | 8.52M | let mut registered_count = 0; |
212 | 8.52M | let mut index_ready = None; |
213 | 8.52M | |
214 | 8.52M | if let Timeout::Now = timeout { |
215 | 8.40M | cx.try_select(Selected::Aborted).unwrap(); |
216 | 8.40M | }112k |
217 | | |
218 | | // Register all operations. |
219 | 8.60M | for (handle, i, _) in handles8.52M .iter_mut() { |
220 | 8.60M | registered_count += 1; |
221 | 8.60M | |
222 | 8.60M | // If registration returns `false`, that means the operation has just become ready. |
223 | 8.60M | if handle.register(Operation::hook::<&dyn SelectHandle>(handle), cx) { |
224 | | // Try aborting select. |
225 | 40.4k | sel = match cx.try_select(Selected::Aborted) { |
226 | 40.4k | Ok(()) => { |
227 | 40.3k | index_ready = Some(*i); |
228 | 40.3k | Selected::Aborted |
229 | | } |
230 | 169 | Err(s) => s, |
231 | | }; |
232 | 40.4k | break; |
233 | 8.56M | } |
234 | 8.56M | |
235 | 8.56M | // If another thread has already selected one of the operations, stop registration. |
236 | 8.56M | sel = cx.selected(); |
237 | 8.56M | if sel != Selected::Waiting { |
238 | 8.42M | break; |
239 | 144k | } |
240 | | } |
241 | | |
242 | 8.51M | if sel == Selected::Waiting { |
243 | | // Check with each operation for how long we're allowed to block, and compute the |
244 | | // earliest deadline. |
245 | 51.8k | let mut deadline: Option<Instant> = match timeout { |
246 | 18.4E | Timeout::Now => return None, |
247 | 51.8k | Timeout::Never => None, |
248 | 48 | Timeout::At(when) => Some(when), |
249 | | }; |
250 | 99.3k | for &(handle, _, _) in handles51.8k .iter() { |
251 | 99.3k | if let Some(x12.7k ) = handle.deadline() { |
252 | 12.7k | deadline = deadline.map(|y| x.min(y)9.16k ).or(Some(x)); |
253 | 86.5k | } |
254 | | } |
255 | | |
256 | | // Block the current thread. |
257 | 51.9k | sel = cx.wait_until(deadline); |
258 | 8.46M | } |
259 | | |
260 | | // Unregister all registered operations. |
261 | 8.60M | for (handle, _, _) in handles.iter_mut().take(registered_count8.51M ) { |
262 | 8.60M | handle.unregister(Operation::hook::<&dyn SelectHandle>(handle)); |
263 | 8.60M | } |
264 | | |
265 | 8.51M | match sel { |
266 | 8.51M | Selected::Waiting => unreachable!()51 , |
267 | | Selected::Aborted => { |
268 | | // If an operation became ready during registration, try selecting it. |
269 | 8.44M | if let Some(index_ready40.2k ) = index_ready { |
270 | 53.7k | for &(handle, i, ptr) in handles40.2k .iter() { |
271 | 53.7k | if i == index_ready && handle.try_select(&mut token)40.4k { |
272 | 39.2k | return Some((i, ptr)); |
273 | 14.4k | } |
274 | | } |
275 | 8.40M | } |
276 | | } |
277 | 5 | Selected::Disconnected => {} |
278 | | Selected::Operation(_) => { |
279 | | // Find the selected operation. |
280 | 74.9k | for (handle, i, ptr) in handles68.5k .iter_mut() { |
281 | | // Is this the selected operation? |
282 | 74.9k | if sel == Selected::Operation(Operation::hook::<&dyn SelectHandle>(handle)) |
283 | | { |
284 | | // Try selecting this operation. |
285 | 68.5k | if handle.accept(&mut token, cx) { |
286 | 68.5k | return Some((*i, *ptr)); |
287 | 41 | } |
288 | 6.34k | } |
289 | | } |
290 | | } |
291 | | } |
292 | | |
293 | 8.41M | None |
294 | 8.51M | })8.51M ; |
295 | | |
296 | | // Return if an operation was selected. |
297 | 8.51M | if let Some((i, ptr107k )) = res { |
298 | 107k | return Some((token, i, ptr)); |
299 | 8.41M | } |
300 | | |
301 | | // Try selecting one of the operations without blocking. |
302 | 8.41M | for &(handle, i, ptr) in handles8.41M .iter() { |
303 | 8.41M | if handle.try_select(&mut token) { |
304 | 3.52k | return Some((token, i, ptr)); |
305 | 8.41M | } |
306 | | } |
307 | | |
308 | 8.41M | match timeout { |
309 | 8.41M | Timeout::Now => return None8.40M , |
310 | 1.07k | Timeout::Never => {} |
311 | 27 | Timeout::At(when) => { |
312 | 27 | if Instant::now() >= when { |
313 | 6 | return None; |
314 | 0 | } |
315 | | } |
316 | | } |
317 | | } |
318 | 9.95M | } |
319 | | |
320 | | /// Runs until one of the operations becomes ready, potentially blocking the current thread. |
321 | 175k | fn run_ready( |
322 | 175k | handles: &mut [(&dyn SelectHandle, usize, *const u8)], |
323 | 175k | timeout: Timeout, |
324 | 175k | ) -> Option<usize> { |
325 | 175k | if handles.is_empty() { |
326 | | // Wait until the timeout and return. |
327 | 4 | match timeout { |
328 | 4 | Timeout::Now => return None2 , |
329 | | Timeout::Never => { |
330 | 0 | utils::sleep_until(None); |
331 | 0 | unreachable!(); |
332 | | } |
333 | 2 | Timeout::At(when) => { |
334 | 2 | utils::sleep_until(Some(when)); |
335 | 2 | return None; |
336 | | } |
337 | | } |
338 | 175k | } |
339 | 175k | |
340 | 175k | // Shuffle the operations for fairness. |
341 | 175k | utils::shuffle(handles); |
342 | | |
343 | 175k | loop { |
344 | 175k | let backoff = Backoff::new(); |
345 | | loop { |
346 | | // Check operations for readiness. |
347 | 355k | for &(handle, i, _) in handles193k .iter() { |
348 | 355k | if handle.is_ready() { |
349 | 173k | return Some(i); |
350 | 182k | } |
351 | | } |
352 | | |
353 | 18.6k | if backoff.is_completed() { |
354 | 79 | break; |
355 | 18.6k | } else { |
356 | 18.6k | backoff.snooze(); |
357 | 18.6k | } |
358 | | } |
359 | | |
360 | | // Check for timeout. |
361 | 79 | match timeout { |
362 | 79 | Timeout::Now => return None22 , |
363 | 50 | Timeout::Never => {} |
364 | 7 | Timeout::At(when) => { |
365 | 7 | if Instant::now() >= when { |
366 | 2 | return None; |
367 | 5 | } |
368 | | } |
369 | | } |
370 | | |
371 | | // Prepare for blocking. |
372 | 55 | let res = Context::with(|cx| { |
373 | 54 | let mut sel = Selected::Waiting; |
374 | 54 | let mut registered_count = 0; |
375 | | |
376 | | // Begin watching all operations. |
377 | 3.90k | for (handle, _, _) in handles54 .iter_mut() { |
378 | 3.90k | registered_count += 1; |
379 | 3.90k | let oper = Operation::hook::<&dyn SelectHandle>(handle); |
380 | 3.90k | |
381 | 3.90k | // If registration returns `false`, that means the operation has just become ready. |
382 | 3.90k | if handle.watch(oper, cx) { |
383 | 6 | sel = match cx.try_select(Selected::Operation(oper)) { |
384 | 6 | Ok(()) => Selected::Operation(oper), |
385 | 0 | Err(s) => s, |
386 | | }; |
387 | 6 | break; |
388 | 3.90k | } |
389 | 3.90k | |
390 | 3.90k | // If another thread has already chosen one of the operations, stop registration. |
391 | 3.90k | sel = cx.selected(); |
392 | 3.90k | if sel != Selected::Waiting { |
393 | 0 | break; |
394 | 3.90k | } |
395 | | } |
396 | | |
397 | 54 | if sel == Selected::Waiting { |
398 | | // Check with each operation for how long we're allowed to block, and compute the |
399 | | // earliest deadline. |
400 | 48 | let mut deadline: Option<Instant> = match timeout { |
401 | 48 | Timeout::Now => unreachable!()0 , |
402 | 43 | Timeout::Never => None, |
403 | 5 | Timeout::At(when) => Some(when), |
404 | | }; |
405 | 3.96k | for &(handle, _, _) in handles48 .iter() { |
406 | 3.96k | if let Some(x164 ) = handle.deadline() { |
407 | 164 | deadline = deadline.map(|y| x.min(y)70 ).or(Some(x)); |
408 | 3.79k | } |
409 | | } |
410 | | |
411 | | // Block the current thread. |
412 | 49 | sel = cx.wait_until(deadline); |
413 | 6 | } |
414 | | |
415 | | // Unwatch all operations. |
416 | 3.80k | for (handle, _, _) in handles.iter_mut().take(registered_count55 ) { |
417 | 3.80k | handle.unwatch(Operation::hook::<&dyn SelectHandle>(handle)); |
418 | 3.80k | } |
419 | | |
420 | 54 | match sel { |
421 | 54 | Selected::Waiting => unreachable!()1 , |
422 | 40 | Selected::Aborted => {} |
423 | 0 | Selected::Disconnected => {} |
424 | | Selected::Operation(_) => { |
425 | 20 | for (handle, i, _) in handles13 .iter_mut() { |
426 | 20 | let oper = Operation::hook::<&dyn SelectHandle>(handle); |
427 | 20 | if sel == Selected::Operation(oper) { |
428 | 13 | return Some(*i); |
429 | 7 | } |
430 | | } |
431 | | } |
432 | | } |
433 | | |
434 | 40 | None |
435 | 55 | }53 ); |
436 | 55 | |
437 | 55 | // Return if an operation became ready. |
438 | 55 | if res.is_some() { |
439 | 19 | return res; |
440 | 36 | } |
441 | | } |
442 | 173k | } |
443 | | |
444 | | /// Attempts to select one of the operations without blocking. |
445 | | #[inline] |
446 | 8.79M | pub fn try_select<'a>( |
447 | 8.79M | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], |
448 | 8.79M | ) -> Result<SelectedOperation<'a>, TrySelectError> { |
449 | 8.79M | match run_select(handles, Timeout::Now) { |
450 | 8.79M | None => Err(TrySelectError)8.39M , |
451 | 402k | Some((token, index, ptr)) => Ok(SelectedOperation { |
452 | 402k | token, |
453 | 402k | index, |
454 | 402k | ptr, |
455 | 402k | _marker: PhantomData, |
456 | 402k | }), |
457 | | } |
458 | 8.79M | } crossbeam_channel::select::try_select Line | Count | Source | 446 | 5.34M | pub fn try_select<'a>( | 447 | 5.34M | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], | 448 | 5.34M | ) -> Result<SelectedOperation<'a>, TrySelectError> { | 449 | 5.34M | match run_select(handles, Timeout::Now) { | 450 | 5.34M | None => Err(TrySelectError)5.14M , | 451 | 200k | Some((token, index, ptr)) => Ok(SelectedOperation { | 452 | 200k | token, | 453 | 200k | index, | 454 | 200k | ptr, | 455 | 200k | _marker: PhantomData, | 456 | 200k | }), | 457 | | } | 458 | 5.34M | } |
crossbeam_channel::select::try_select Line | Count | Source | 446 | 1 | pub fn try_select<'a>( | 447 | 1 | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], | 448 | 1 | ) -> Result<SelectedOperation<'a>, TrySelectError> { | 449 | 1 | match run_select(handles, Timeout::Now) { | 450 | 1 | None => Err(TrySelectError), | 451 | 0 | Some((token, index, ptr)) => Ok(SelectedOperation { | 452 | 0 | token, | 453 | 0 | index, | 454 | 0 | ptr, | 455 | 0 | _marker: PhantomData, | 456 | 0 | }), | 457 | | } | 458 | 1 | } |
crossbeam_channel::select::try_select Line | Count | Source | 446 | 2.21k | pub fn try_select<'a>( | 447 | 2.21k | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], | 448 | 2.21k | ) -> Result<SelectedOperation<'a>, TrySelectError> { | 449 | 2.21k | match run_select(handles, Timeout::Now) { | 450 | 2.21k | None => Err(TrySelectError)206 , | 451 | 2.01k | Some((token, index, ptr)) => Ok(SelectedOperation { | 452 | 2.01k | token, | 453 | 2.01k | index, | 454 | 2.01k | ptr, | 455 | 2.01k | _marker: PhantomData, | 456 | 2.01k | }), | 457 | | } | 458 | 2.21k | } |
crossbeam_channel::select::try_select Line | Count | Source | 446 | 3.45M | pub fn try_select<'a>( | 447 | 3.45M | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], | 448 | 3.45M | ) -> Result<SelectedOperation<'a>, TrySelectError> { | 449 | 3.45M | match run_select(handles, Timeout::Now) { | 450 | 3.45M | None => Err(TrySelectError)3.25M , | 451 | 200k | Some((token, index, ptr)) => Ok(SelectedOperation { | 452 | 200k | token, | 453 | 200k | index, | 454 | 200k | ptr, | 455 | 200k | _marker: PhantomData, | 456 | 200k | }), | 457 | | } | 458 | 3.45M | } |
|
459 | | |
460 | | /// Blocks until one of the operations becomes ready and selects it. |
461 | | #[inline] |
462 | 747k | pub fn select<'a>( |
463 | 747k | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], |
464 | 747k | ) -> SelectedOperation<'a> { |
465 | 747k | if handles.is_empty() { |
466 | 0 | panic!("no operations have been added to `Select`"); |
467 | 747k | } |
468 | 747k | |
469 | 747k | let (token, index, ptr) = run_select(handles, Timeout::Never).unwrap(); |
470 | 747k | SelectedOperation { |
471 | 747k | token, |
472 | 747k | index, |
473 | 747k | ptr, |
474 | 747k | _marker: PhantomData, |
475 | 747k | } |
476 | 747k | } crossbeam_channel::select::select Line | Count | Source | 462 | 39.8k | pub fn select<'a>( | 463 | 39.8k | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], | 464 | 39.8k | ) -> SelectedOperation<'a> { | 465 | 39.8k | if handles.is_empty() { | 466 | 0 | panic!("no operations have been added to `Select`"); | 467 | 39.8k | } | 468 | 39.8k | | 469 | 39.8k | let (token, index, ptr) = run_select(handles, Timeout::Never).unwrap(); | 470 | 39.8k | SelectedOperation { | 471 | 39.8k | token, | 472 | 39.8k | index, | 473 | 39.8k | ptr, | 474 | 39.8k | _marker: PhantomData, | 475 | 39.8k | } | 476 | 39.8k | } |
crossbeam_channel::select::select Line | Count | Source | 462 | 295k | pub fn select<'a>( | 463 | 295k | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], | 464 | 295k | ) -> SelectedOperation<'a> { | 465 | 295k | if handles.is_empty() { | 466 | 0 | panic!("no operations have been added to `Select`"); | 467 | 295k | } | 468 | 295k | | 469 | 295k | let (token, index, ptr) = run_select(handles, Timeout::Never).unwrap(); | 470 | 295k | SelectedOperation { | 471 | 295k | token, | 472 | 295k | index, | 473 | 295k | ptr, | 474 | 295k | _marker: PhantomData, | 475 | 295k | } | 476 | 295k | } |
crossbeam_channel::select::select Line | Count | Source | 462 | 10.0k | pub fn select<'a>( | 463 | 10.0k | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], | 464 | 10.0k | ) -> SelectedOperation<'a> { | 465 | 10.0k | if handles.is_empty() { | 466 | 0 | panic!("no operations have been added to `Select`"); | 467 | 10.0k | } | 468 | 10.0k | | 469 | 10.0k | let (token, index, ptr) = run_select(handles, Timeout::Never).unwrap(); | 470 | 10.0k | SelectedOperation { | 471 | 10.0k | token, | 472 | 10.0k | index, | 473 | 10.0k | ptr, | 474 | 10.0k | _marker: PhantomData, | 475 | 10.0k | } | 476 | 10.0k | } |
crossbeam_channel::select::select Line | Count | Source | 462 | 3.97k | pub fn select<'a>( | 463 | 3.97k | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], | 464 | 3.97k | ) -> SelectedOperation<'a> { | 465 | 3.97k | if handles.is_empty() { | 466 | 0 | panic!("no operations have been added to `Select`"); | 467 | 3.97k | } | 468 | 3.97k | | 469 | 3.97k | let (token, index, ptr) = run_select(handles, Timeout::Never).unwrap(); | 470 | 3.97k | SelectedOperation { | 471 | 3.97k | token, | 472 | 3.97k | index, | 473 | 3.97k | ptr, | 474 | 3.97k | _marker: PhantomData, | 475 | 3.97k | } | 476 | 3.97k | } |
crossbeam_channel::select::select Line | Count | Source | 462 | 19.9k | pub fn select<'a>( | 463 | 19.9k | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], | 464 | 19.9k | ) -> SelectedOperation<'a> { | 465 | 19.9k | if handles.is_empty() { | 466 | 0 | panic!("no operations have been added to `Select`"); | 467 | 19.9k | } | 468 | 19.9k | | 469 | 19.9k | let (token, index, ptr) = run_select(handles, Timeout::Never).unwrap(); | 470 | 19.9k | SelectedOperation { | 471 | 19.9k | token, | 472 | 19.9k | index, | 473 | 19.9k | ptr, | 474 | 19.9k | _marker: PhantomData, | 475 | 19.9k | } | 476 | 19.9k | } |
crossbeam_channel::select::select Line | Count | Source | 462 | 3.58k | pub fn select<'a>( | 463 | 3.58k | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], | 464 | 3.58k | ) -> SelectedOperation<'a> { | 465 | 3.58k | if handles.is_empty() { | 466 | 0 | panic!("no operations have been added to `Select`"); | 467 | 3.58k | } | 468 | 3.58k | | 469 | 3.58k | let (token, index, ptr) = run_select(handles, Timeout::Never).unwrap(); | 470 | 3.58k | SelectedOperation { | 471 | 3.58k | token, | 472 | 3.58k | index, | 473 | 3.58k | ptr, | 474 | 3.58k | _marker: PhantomData, | 475 | 3.58k | } | 476 | 3.58k | } |
crossbeam_channel::select::select Line | Count | Source | 462 | 1 | pub fn select<'a>( | 463 | 1 | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], | 464 | 1 | ) -> SelectedOperation<'a> { | 465 | 1 | if handles.is_empty() { | 466 | 0 | panic!("no operations have been added to `Select`"); | 467 | 1 | } | 468 | 1 | | 469 | 1 | let (token, index, ptr) = run_select(handles, Timeout::Never).unwrap(); | 470 | 1 | SelectedOperation { | 471 | 1 | token, | 472 | 1 | index, | 473 | 1 | ptr, | 474 | 1 | _marker: PhantomData, | 475 | 1 | } | 476 | 1 | } |
crossbeam_channel::select::select Line | Count | Source | 462 | 19.8k | pub fn select<'a>( | 463 | 19.8k | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], | 464 | 19.8k | ) -> SelectedOperation<'a> { | 465 | 19.8k | if handles.is_empty() { | 466 | 0 | panic!("no operations have been added to `Select`"); | 467 | 19.8k | } | 468 | 19.8k | | 469 | 19.8k | let (token, index, ptr) = run_select(handles, Timeout::Never).unwrap(); | 470 | 19.8k | SelectedOperation { | 471 | 19.8k | token, | 472 | 19.8k | index, | 473 | 19.8k | ptr, | 474 | 19.8k | _marker: PhantomData, | 475 | 19.8k | } | 476 | 19.8k | } |
crossbeam_channel::select::select Line | Count | Source | 462 | 243k | pub fn select<'a>( | 463 | 243k | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], | 464 | 243k | ) -> SelectedOperation<'a> { | 465 | 243k | if handles.is_empty() { | 466 | 0 | panic!("no operations have been added to `Select`"); | 467 | 243k | } | 468 | 243k | | 469 | 243k | let (token, index, ptr) = run_select(handles, Timeout::Never).unwrap(); | 470 | 243k | SelectedOperation { | 471 | 243k | token, | 472 | 243k | index, | 473 | 243k | ptr, | 474 | 243k | _marker: PhantomData, | 475 | 243k | } | 476 | 243k | } |
crossbeam_channel::select::select Line | Count | Source | 462 | 111k | pub fn select<'a>( | 463 | 111k | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], | 464 | 111k | ) -> SelectedOperation<'a> { | 465 | 111k | if handles.is_empty() { | 466 | 0 | panic!("no operations have been added to `Select`"); | 467 | 111k | } | 468 | 111k | | 469 | 111k | let (token, index, ptr) = run_select(handles, Timeout::Never).unwrap(); | 470 | 111k | SelectedOperation { | 471 | 111k | token, | 472 | 111k | index, | 473 | 111k | ptr, | 474 | 111k | _marker: PhantomData, | 475 | 111k | } | 476 | 111k | } |
|
477 | | |
478 | | /// Blocks for a limited time until one of the operations becomes ready and selects it. |
479 | | #[inline] |
480 | 400k | pub fn select_timeout<'a>( |
481 | 400k | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], |
482 | 400k | timeout: Duration, |
483 | 400k | ) -> Result<SelectedOperation<'a>, SelectTimeoutError> { |
484 | 400k | select_deadline(handles, Instant::now() + timeout) |
485 | 400k | } crossbeam_channel::select::select_timeout Line | Count | Source | 480 | 200k | pub fn select_timeout<'a>( | 481 | 200k | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], | 482 | 200k | timeout: Duration, | 483 | 200k | ) -> Result<SelectedOperation<'a>, SelectTimeoutError> { | 484 | 200k | select_deadline(handles, Instant::now() + timeout) | 485 | 200k | } |
crossbeam_channel::select::select_timeout Line | Count | Source | 480 | 200k | pub fn select_timeout<'a>( | 481 | 200k | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], | 482 | 200k | timeout: Duration, | 483 | 200k | ) -> Result<SelectedOperation<'a>, SelectTimeoutError> { | 484 | 200k | select_deadline(handles, Instant::now() + timeout) | 485 | 200k | } |
|
486 | | |
487 | | /// Blocks until a given deadline, or until one of the operations becomes ready and selects it. |
488 | | #[inline] |
489 | 400k | pub(crate) fn select_deadline<'a>( |
490 | 400k | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], |
491 | 400k | deadline: Instant, |
492 | 400k | ) -> Result<SelectedOperation<'a>, SelectTimeoutError> { |
493 | 400k | match run_select(handles, Timeout::At(deadline)) { |
494 | 400k | None => Err(SelectTimeoutError)9 , |
495 | 400k | Some((token, index, ptr)) => Ok(SelectedOperation { |
496 | 400k | token, |
497 | 400k | index, |
498 | 400k | ptr, |
499 | 400k | _marker: PhantomData, |
500 | 400k | }), |
501 | | } |
502 | 400k | } crossbeam_channel::select::select_deadline Line | Count | Source | 489 | 200k | pub(crate) fn select_deadline<'a>( | 490 | 200k | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], | 491 | 200k | deadline: Instant, | 492 | 200k | ) -> Result<SelectedOperation<'a>, SelectTimeoutError> { | 493 | 200k | match run_select(handles, Timeout::At(deadline)) { | 494 | 200k | None => Err(SelectTimeoutError)4 , | 495 | 200k | Some((token, index, ptr)) => Ok(SelectedOperation { | 496 | 200k | token, | 497 | 200k | index, | 498 | 200k | ptr, | 499 | 200k | _marker: PhantomData, | 500 | 200k | }), | 501 | | } | 502 | 200k | } |
crossbeam_channel::select::select_deadline Line | Count | Source | 489 | 200k | pub(crate) fn select_deadline<'a>( | 490 | 200k | handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], | 491 | 200k | deadline: Instant, | 492 | 200k | ) -> Result<SelectedOperation<'a>, SelectTimeoutError> { | 493 | 200k | match run_select(handles, Timeout::At(deadline)) { | 494 | 200k | None => Err(SelectTimeoutError)5 , | 495 | 200k | Some((token, index, ptr)) => Ok(SelectedOperation { | 496 | 200k | token, | 497 | 200k | index, | 498 | 200k | ptr, | 499 | 200k | _marker: PhantomData, | 500 | 200k | }), | 501 | | } | 502 | 200k | } |
|
503 | | |
504 | | /// Selects from a set of channel operations. |
505 | | /// |
506 | | /// `Select` allows you to define a set of channel operations, wait until any one of them becomes |
507 | | /// ready, and finally execute it. If multiple operations are ready at the same time, a random one |
508 | | /// among them is selected. |
509 | | /// |
510 | | /// An operation is considered to be ready if it doesn't have to block. Note that it is ready even |
511 | | /// when it will simply return an error because the channel is disconnected. |
512 | | /// |
513 | | /// The [`select!`] macro is a convenience wrapper around `Select`. However, it cannot select over a |
514 | | /// dynamically created list of channel operations. |
515 | | /// |
516 | | /// Once a list of operations has been built with `Select`, there are two different ways of |
517 | | /// proceeding: |
518 | | /// |
519 | | /// * Select an operation with [`try_select`], [`select`], or [`select_timeout`]. If successful, |
520 | | /// the returned selected operation has already begun and **must** be completed. If we don't |
521 | | /// complete it, a panic will occur. |
522 | | /// |
523 | | /// * Wait for an operation to become ready with [`try_ready`], [`ready`], or [`ready_timeout`]. If |
524 | | /// successful, we may attempt to execute the operation, but are not obliged to. In fact, it's |
525 | | /// possible for another thread to make the operation not ready just before we try executing it, |
526 | | /// so it's wise to use a retry loop. However, note that these methods might return with success |
527 | | /// spuriously, so it's a good idea to always double check if the operation is really ready. |
528 | | /// |
529 | | /// # Examples |
530 | | /// |
531 | | /// Use [`select`] to receive a message from a list of receivers: |
532 | | /// |
533 | | /// ``` |
534 | | /// use crossbeam_channel::{Receiver, RecvError, Select}; |
535 | | /// |
536 | | /// fn recv_multiple<T>(rs: &[Receiver<T>]) -> Result<T, RecvError> { |
537 | | /// // Build a list of operations. |
538 | | /// let mut sel = Select::new(); |
539 | | /// for r in rs { |
540 | | /// sel.recv(r); |
541 | | /// } |
542 | | /// |
543 | | /// // Complete the selected operation. |
544 | | /// let oper = sel.select(); |
545 | | /// let index = oper.index(); |
546 | | /// oper.recv(&rs[index]) |
547 | | /// } |
548 | | /// ``` |
549 | | /// |
550 | | /// Use [`ready`] to receive a message from a list of receivers: |
551 | | /// |
552 | | /// ``` |
553 | | /// use crossbeam_channel::{Receiver, RecvError, Select}; |
554 | | /// |
555 | | /// fn recv_multiple<T>(rs: &[Receiver<T>]) -> Result<T, RecvError> { |
556 | | /// // Build a list of operations. |
557 | | /// let mut sel = Select::new(); |
558 | | /// for r in rs { |
559 | | /// sel.recv(r); |
560 | | /// } |
561 | | /// |
562 | | /// loop { |
563 | | /// // Wait until a receive operation becomes ready and try executing it. |
564 | | /// let index = sel.ready(); |
565 | | /// let res = rs[index].try_recv(); |
566 | | /// |
567 | | /// // If the operation turns out not to be ready, retry. |
568 | | /// if let Err(e) = res { |
569 | | /// if e.is_empty() { |
570 | | /// continue; |
571 | | /// } |
572 | | /// } |
573 | | /// |
574 | | /// // Success! |
575 | | /// return res.map_err(|_| RecvError); |
576 | | /// } |
577 | | /// } |
578 | | /// ``` |
579 | | /// |
580 | | /// [`try_select`]: Select::try_select |
581 | | /// [`select`]: Select::select |
582 | | /// [`select_timeout`]: Select::select_timeout |
583 | | /// [`try_ready`]: Select::try_ready |
584 | | /// [`ready`]: Select::ready |
585 | | /// [`ready_timeout`]: Select::ready_timeout |
586 | | pub struct Select<'a> { |
587 | | /// A list of senders and receivers participating in selection. |
588 | | handles: Vec<(&'a dyn SelectHandle, usize, *const u8)>, |
589 | | |
590 | | /// The next index to assign to an operation. |
591 | | next_index: usize, |
592 | | } |
593 | | |
594 | | unsafe impl Send for Select<'_> {} |
595 | | unsafe impl Sync for Select<'_> {} |
596 | | |
597 | | impl<'a> Select<'a> { |
598 | | /// Creates an empty list of channel operations for selection. |
599 | | /// |
600 | | /// # Examples |
601 | | /// |
602 | | /// ``` |
603 | | /// use crossbeam_channel::Select; |
604 | | /// |
605 | | /// let mut sel = Select::new(); |
606 | | /// |
607 | | /// // The list of operations is empty, which means no operation can be selected. |
608 | | /// assert!(sel.try_select().is_err()); |
609 | | /// ``` |
610 | 5.97M | pub fn new() -> Select<'a> { |
611 | 5.97M | Select { |
612 | 5.97M | handles: Vec::with_capacity(4), |
613 | 5.97M | next_index: 0, |
614 | 5.97M | } |
615 | 5.97M | } |
616 | | |
617 | | /// Adds a send operation. |
618 | | /// |
619 | | /// Returns the index of the added operation. |
620 | | /// |
621 | | /// # Examples |
622 | | /// |
623 | | /// ``` |
624 | | /// use crossbeam_channel::{unbounded, Select}; |
625 | | /// |
626 | | /// let (s, r) = unbounded::<i32>(); |
627 | | /// |
628 | | /// let mut sel = Select::new(); |
629 | | /// let index = sel.send(&s); |
630 | | /// ``` |
631 | 1.79M | pub fn send<T>(&mut self, s: &'a Sender<T>) -> usize { |
632 | 1.79M | let i = self.next_index; |
633 | 1.79M | let ptr = s as *const Sender<_> as *const u8; |
634 | 1.79M | self.handles.push((s, i, ptr)); |
635 | 1.79M | self.next_index += 1; |
636 | 1.79M | i |
637 | 1.79M | } <crossbeam_channel::select::Select>::send::<i32> Line | Count | Source | 631 | 1.31M | pub fn send<T>(&mut self, s: &'a Sender<T>) -> usize { | 632 | 1.31M | let i = self.next_index; | 633 | 1.31M | let ptr = s as *const Sender<_> as *const u8; | 634 | 1.31M | self.handles.push((s, i, ptr)); | 635 | 1.31M | self.next_index += 1; | 636 | 1.31M | i | 637 | 1.31M | } |
<crossbeam_channel::select::Select>::send::<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>> Line | Count | Source | 631 | 3.00k | pub fn send<T>(&mut self, s: &'a Sender<T>) -> usize { | 632 | 3.00k | let i = self.next_index; | 633 | 3.00k | let ptr = s as *const Sender<_> as *const u8; | 634 | 3.00k | self.handles.push((s, i, ptr)); | 635 | 3.00k | self.next_index += 1; | 636 | 3.00k | i | 637 | 3.00k | } |
<crossbeam_channel::select::Select>::send::<()> Line | Count | Source | 631 | 20.5k | pub fn send<T>(&mut self, s: &'a Sender<T>) -> usize { | 632 | 20.5k | let i = self.next_index; | 633 | 20.5k | let ptr = s as *const Sender<_> as *const u8; | 634 | 20.5k | self.handles.push((s, i, ptr)); | 635 | 20.5k | self.next_index += 1; | 636 | 20.5k | i | 637 | 20.5k | } |
<crossbeam_channel::select::Select>::send::<usize> Line | Count | Source | 631 | 59.8k | pub fn send<T>(&mut self, s: &'a Sender<T>) -> usize { | 632 | 59.8k | let i = self.next_index; | 633 | 59.8k | let ptr = s as *const Sender<_> as *const u8; | 634 | 59.8k | self.handles.push((s, i, ptr)); | 635 | 59.8k | self.next_index += 1; | 636 | 59.8k | i | 637 | 59.8k | } |
<crossbeam_channel::select::Select>::send::<i32> Line | Count | Source | 631 | 124k | pub fn send<T>(&mut self, s: &'a Sender<T>) -> usize { | 632 | 124k | let i = self.next_index; | 633 | 124k | let ptr = s as *const Sender<_> as *const u8; | 634 | 124k | self.handles.push((s, i, ptr)); | 635 | 124k | self.next_index += 1; | 636 | 124k | i | 637 | 124k | } |
<crossbeam_channel::select::Select>::send::<i32> Line | Count | Source | 631 | 30 | pub fn send<T>(&mut self, s: &'a Sender<T>) -> usize { | 632 | 30 | let i = self.next_index; | 633 | 30 | let ptr = s as *const Sender<_> as *const u8; | 634 | 30 | self.handles.push((s, i, ptr)); | 635 | 30 | self.next_index += 1; | 636 | 30 | i | 637 | 30 | } |
<crossbeam_channel::select::Select>::send::<()> Line | Count | Source | 631 | 207k | pub fn send<T>(&mut self, s: &'a Sender<T>) -> usize { | 632 | 207k | let i = self.next_index; | 633 | 207k | let ptr = s as *const Sender<_> as *const u8; | 634 | 207k | self.handles.push((s, i, ptr)); | 635 | 207k | self.next_index += 1; | 636 | 207k | i | 637 | 207k | } |
<crossbeam_channel::select::Select>::send::<usize> Line | Count | Source | 631 | 59.5k | pub fn send<T>(&mut self, s: &'a Sender<T>) -> usize { | 632 | 59.5k | let i = self.next_index; | 633 | 59.5k | let ptr = s as *const Sender<_> as *const u8; | 634 | 59.5k | self.handles.push((s, i, ptr)); | 635 | 59.5k | self.next_index += 1; | 636 | 59.5k | i | 637 | 59.5k | } |
<crossbeam_channel::select::Select>::send::<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>> Line | Count | Source | 631 | 3.00k | pub fn send<T>(&mut self, s: &'a Sender<T>) -> usize { | 632 | 3.00k | let i = self.next_index; | 633 | 3.00k | let ptr = s as *const Sender<_> as *const u8; | 634 | 3.00k | self.handles.push((s, i, ptr)); | 635 | 3.00k | self.next_index += 1; | 636 | 3.00k | i | 637 | 3.00k | } |
|
638 | | |
639 | | /// Adds a receive operation. |
640 | | /// |
641 | | /// Returns the index of the added operation. |
642 | | /// |
643 | | /// # Examples |
644 | | /// |
645 | | /// ``` |
646 | | /// use crossbeam_channel::{unbounded, Select}; |
647 | | /// |
648 | | /// let (s, r) = unbounded::<i32>(); |
649 | | /// |
650 | | /// let mut sel = Select::new(); |
651 | | /// let index = sel.recv(&r); |
652 | | /// ``` |
653 | 6.47M | pub fn recv<T>(&mut self, r: &'a Receiver<T>) -> usize { |
654 | 6.47M | let i = self.next_index; |
655 | 6.47M | let ptr = r as *const Receiver<_> as *const u8; |
656 | 6.47M | self.handles.push((r, i, ptr)); |
657 | 6.47M | self.next_index += 1; |
658 | 6.47M | i |
659 | 6.47M | } <crossbeam_channel::select::Select>::recv::<usize> Line | Count | Source | 653 | 59.8k | pub fn recv<T>(&mut self, r: &'a Receiver<T>) -> usize { | 654 | 59.8k | let i = self.next_index; | 655 | 59.8k | let ptr = r as *const Receiver<_> as *const u8; | 656 | 59.8k | self.handles.push((r, i, ptr)); | 657 | 59.8k | self.next_index += 1; | 658 | 59.8k | i | 659 | 59.8k | } |
<crossbeam_channel::select::Select>::recv::<()> Line | Count | Source | 653 | 3.88M | pub fn recv<T>(&mut self, r: &'a Receiver<T>) -> usize { | 654 | 3.88M | let i = self.next_index; | 655 | 3.88M | let ptr = r as *const Receiver<_> as *const u8; | 656 | 3.88M | self.handles.push((r, i, ptr)); | 657 | 3.88M | self.next_index += 1; | 658 | 3.88M | i | 659 | 3.88M | } |
<crossbeam_channel::select::Select>::recv::<std::time::Instant> Line | Count | Source | 653 | 20.0k | pub fn recv<T>(&mut self, r: &'a Receiver<T>) -> usize { | 654 | 20.0k | let i = self.next_index; | 655 | 20.0k | let ptr = r as *const Receiver<_> as *const u8; | 656 | 20.0k | self.handles.push((r, i, ptr)); | 657 | 20.0k | self.next_index += 1; | 658 | 20.0k | i | 659 | 20.0k | } |
<crossbeam_channel::select::Select>::recv::<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>> Line | Count | Source | 653 | 3.00k | pub fn recv<T>(&mut self, r: &'a Receiver<T>) -> usize { | 654 | 3.00k | let i = self.next_index; | 655 | 3.00k | let ptr = r as *const Receiver<_> as *const u8; | 656 | 3.00k | self.handles.push((r, i, ptr)); | 657 | 3.00k | self.next_index += 1; | 658 | 3.00k | i | 659 | 3.00k | } |
<crossbeam_channel::select::Select>::recv::<i32> Line | Count | Source | 653 | 798k | pub fn recv<T>(&mut self, r: &'a Receiver<T>) -> usize { | 654 | 798k | let i = self.next_index; | 655 | 798k | let ptr = r as *const Receiver<_> as *const u8; | 656 | 798k | self.handles.push((r, i, ptr)); | 657 | 798k | self.next_index += 1; | 658 | 798k | i | 659 | 798k | } |
<crossbeam_channel::select::Select>::recv::<std::time::Instant> Line | Count | Source | 653 | 1.17M | pub fn recv<T>(&mut self, r: &'a Receiver<T>) -> usize { | 654 | 1.17M | let i = self.next_index; | 655 | 1.17M | let ptr = r as *const Receiver<_> as *const u8; | 656 | 1.17M | self.handles.push((r, i, ptr)); | 657 | 1.17M | self.next_index += 1; | 658 | 1.17M | i | 659 | 1.17M | } |
<crossbeam_channel::select::Select>::recv::<std::time::Instant> Line | Count | Source | 653 | 72 | pub fn recv<T>(&mut self, r: &'a Receiver<T>) -> usize { | 654 | 72 | let i = self.next_index; | 655 | 72 | let ptr = r as *const Receiver<_> as *const u8; | 656 | 72 | self.handles.push((r, i, ptr)); | 657 | 72 | self.next_index += 1; | 658 | 72 | i | 659 | 72 | } |
<crossbeam_channel::select::Select>::recv::<i32> Line | Count | Source | 653 | 124k | pub fn recv<T>(&mut self, r: &'a Receiver<T>) -> usize { | 654 | 124k | let i = self.next_index; | 655 | 124k | let ptr = r as *const Receiver<_> as *const u8; | 656 | 124k | self.handles.push((r, i, ptr)); | 657 | 124k | self.next_index += 1; | 658 | 124k | i | 659 | 124k | } |
<crossbeam_channel::select::Select>::recv::<usize> Line | Count | Source | 653 | 59.6k | pub fn recv<T>(&mut self, r: &'a Receiver<T>) -> usize { | 654 | 59.6k | let i = self.next_index; | 655 | 59.6k | let ptr = r as *const Receiver<_> as *const u8; | 656 | 59.6k | self.handles.push((r, i, ptr)); | 657 | 59.6k | self.next_index += 1; | 658 | 59.6k | i | 659 | 59.6k | } |
<crossbeam_channel::select::Select>::recv::<std::time::Instant> Line | Count | Source | 653 | 20.0k | pub fn recv<T>(&mut self, r: &'a Receiver<T>) -> usize { | 654 | 20.0k | let i = self.next_index; | 655 | 20.0k | let ptr = r as *const Receiver<_> as *const u8; | 656 | 20.0k | self.handles.push((r, i, ptr)); | 657 | 20.0k | self.next_index += 1; | 658 | 20.0k | i | 659 | 20.0k | } |
<crossbeam_channel::select::Select>::recv::<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>> Line | Count | Source | 653 | 3.00k | pub fn recv<T>(&mut self, r: &'a Receiver<T>) -> usize { | 654 | 3.00k | let i = self.next_index; | 655 | 3.00k | let ptr = r as *const Receiver<_> as *const u8; | 656 | 3.00k | self.handles.push((r, i, ptr)); | 657 | 3.00k | self.next_index += 1; | 658 | 3.00k | i | 659 | 3.00k | } |
<crossbeam_channel::select::Select>::recv::<i32> Line | Count | Source | 653 | 53 | pub fn recv<T>(&mut self, r: &'a Receiver<T>) -> usize { | 654 | 53 | let i = self.next_index; | 655 | 53 | let ptr = r as *const Receiver<_> as *const u8; | 656 | 53 | self.handles.push((r, i, ptr)); | 657 | 53 | self.next_index += 1; | 658 | 53 | i | 659 | 53 | } |
<crossbeam_channel::select::Select>::recv::<()> Line | Count | Source | 653 | 319k | pub fn recv<T>(&mut self, r: &'a Receiver<T>) -> usize { | 654 | 319k | let i = self.next_index; | 655 | 319k | let ptr = r as *const Receiver<_> as *const u8; | 656 | 319k | self.handles.push((r, i, ptr)); | 657 | 319k | self.next_index += 1; | 658 | 319k | i | 659 | 319k | } |
|
660 | | |
661 | | /// Removes a previously added operation. |
662 | | /// |
663 | | /// This is useful when an operation is selected because the channel got disconnected and we |
664 | | /// want to try again to select a different operation instead. |
665 | | /// |
666 | | /// If new operations are added after removing some, the indices of removed operations will not |
667 | | /// be reused. |
668 | | /// |
669 | | /// # Panics |
670 | | /// |
671 | | /// An attempt to remove a non-existing or already removed operation will panic. |
672 | | /// |
673 | | /// # Examples |
674 | | /// |
675 | | /// ``` |
676 | | /// use crossbeam_channel::{unbounded, Select}; |
677 | | /// |
678 | | /// let (s1, r1) = unbounded::<i32>(); |
679 | | /// let (_, r2) = unbounded::<i32>(); |
680 | | /// |
681 | | /// let mut sel = Select::new(); |
682 | | /// let oper1 = sel.recv(&r1); |
683 | | /// let oper2 = sel.recv(&r2); |
684 | | /// |
685 | | /// // Both operations are initially ready, so a random one will be executed. |
686 | | /// let oper = sel.select(); |
687 | | /// assert_eq!(oper.index(), oper2); |
688 | | /// assert!(oper.recv(&r2).is_err()); |
689 | | /// sel.remove(oper2); |
690 | | /// |
691 | | /// s1.send(10).unwrap(); |
692 | | /// |
693 | | /// let oper = sel.select(); |
694 | | /// assert_eq!(oper.index(), oper1); |
695 | | /// assert_eq!(oper.recv(&r1), Ok(10)); |
696 | | /// ``` |
697 | 1 | pub fn remove(&mut self, index: usize) { |
698 | | assert!( |
699 | 1 | index < self.next_index, |
700 | 0 | "index out of bounds; {} >= {}", |
701 | 0 | index, |
702 | 0 | self.next_index, |
703 | | ); |
704 | | |
705 | 1 | let i = self |
706 | 1 | .handles |
707 | 1 | .iter() |
708 | 1 | .enumerate() |
709 | 1 | .find(|(_, (_, i, _))| *i == index) |
710 | 1 | .expect("no operation with this index") |
711 | 1 | .0; |
712 | 1 | |
713 | 1 | self.handles.swap_remove(i); |
714 | 1 | } |
715 | | |
716 | | /// Attempts to select one of the operations without blocking. |
717 | | /// |
718 | | /// If an operation is ready, it is selected and returned. If multiple operations are ready at |
719 | | /// the same time, a random one among them is selected. If none of the operations are ready, an |
720 | | /// error is returned. |
721 | | /// |
722 | | /// An operation is considered to be ready if it doesn't have to block. Note that it is ready |
723 | | /// even when it will simply return an error because the channel is disconnected. |
724 | | /// |
725 | | /// The selected operation must be completed with [`SelectedOperation::send`] |
726 | | /// or [`SelectedOperation::recv`]. |
727 | | /// |
728 | | /// # Examples |
729 | | /// |
730 | | /// ``` |
731 | | /// use crossbeam_channel::{unbounded, Select}; |
732 | | /// |
733 | | /// let (s1, r1) = unbounded(); |
734 | | /// let (s2, r2) = unbounded(); |
735 | | /// |
736 | | /// s1.send(10).unwrap(); |
737 | | /// s2.send(20).unwrap(); |
738 | | /// |
739 | | /// let mut sel = Select::new(); |
740 | | /// let oper1 = sel.recv(&r1); |
741 | | /// let oper2 = sel.recv(&r2); |
742 | | /// |
743 | | /// // Both operations are initially ready, so a random one will be executed. |
744 | | /// let oper = sel.try_select(); |
745 | | /// match oper { |
746 | | /// Err(_) => panic!("both operations should be ready"), |
747 | | /// Ok(oper) => match oper.index() { |
748 | | /// i if i == oper1 => assert_eq!(oper.recv(&r1), Ok(10)), |
749 | | /// i if i == oper2 => assert_eq!(oper.recv(&r2), Ok(20)), |
750 | | /// _ => unreachable!(), |
751 | | /// } |
752 | | /// } |
753 | | /// ``` |
754 | 5.34M | pub fn try_select(&mut self) -> Result<SelectedOperation<'a>, TrySelectError> { |
755 | 5.34M | try_select(&mut self.handles) |
756 | 5.34M | } |
757 | | |
758 | | /// Blocks until one of the operations becomes ready and selects it. |
759 | | /// |
760 | | /// Once an operation becomes ready, it is selected and returned. If multiple operations are |
761 | | /// ready at the same time, a random one among them is selected. |
762 | | /// |
763 | | /// An operation is considered to be ready if it doesn't have to block. Note that it is ready |
764 | | /// even when it will simply return an error because the channel is disconnected. |
765 | | /// |
766 | | /// The selected operation must be completed with [`SelectedOperation::send`] |
767 | | /// or [`SelectedOperation::recv`]. |
768 | | /// |
769 | | /// # Panics |
770 | | /// |
771 | | /// Panics if no operations have been added to `Select`. |
772 | | /// |
773 | | /// # Examples |
774 | | /// |
775 | | /// ``` |
776 | | /// use std::thread; |
777 | | /// use std::time::Duration; |
778 | | /// use crossbeam_channel::{unbounded, Select}; |
779 | | /// |
780 | | /// let (s1, r1) = unbounded(); |
781 | | /// let (s2, r2) = unbounded(); |
782 | | /// |
783 | | /// thread::spawn(move || { |
784 | | /// thread::sleep(Duration::from_secs(1)); |
785 | | /// s1.send(10).unwrap(); |
786 | | /// }); |
787 | | /// thread::spawn(move || s2.send(20).unwrap()); |
788 | | /// |
789 | | /// let mut sel = Select::new(); |
790 | | /// let oper1 = sel.recv(&r1); |
791 | | /// let oper2 = sel.recv(&r2); |
792 | | /// |
793 | | /// // The second operation will be selected because it becomes ready first. |
794 | | /// let oper = sel.select(); |
795 | | /// match oper.index() { |
796 | | /// i if i == oper1 => assert_eq!(oper.recv(&r1), Ok(10)), |
797 | | /// i if i == oper2 => assert_eq!(oper.recv(&r2), Ok(20)), |
798 | | /// _ => unreachable!(), |
799 | | /// } |
800 | | /// ``` |
801 | 295k | pub fn select(&mut self) -> SelectedOperation<'a> { |
802 | 295k | select(&mut self.handles) |
803 | 295k | } |
804 | | |
805 | | /// Blocks for a limited time until one of the operations becomes ready and selects it. |
806 | | /// |
807 | | /// If an operation becomes ready, it is selected and returned. If multiple operations are |
808 | | /// ready at the same time, a random one among them is selected. If none of the operations |
809 | | /// become ready for the specified duration, an error is returned. |
810 | | /// |
811 | | /// An operation is considered to be ready if it doesn't have to block. Note that it is ready |
812 | | /// even when it will simply return an error because the channel is disconnected. |
813 | | /// |
814 | | /// The selected operation must be completed with [`SelectedOperation::send`] |
815 | | /// or [`SelectedOperation::recv`]. |
816 | | /// |
817 | | /// # Examples |
818 | | /// |
819 | | /// ``` |
820 | | /// use std::thread; |
821 | | /// use std::time::Duration; |
822 | | /// use crossbeam_channel::{unbounded, Select}; |
823 | | /// |
824 | | /// let (s1, r1) = unbounded(); |
825 | | /// let (s2, r2) = unbounded(); |
826 | | /// |
827 | | /// thread::spawn(move || { |
828 | | /// thread::sleep(Duration::from_secs(1)); |
829 | | /// s1.send(10).unwrap(); |
830 | | /// }); |
831 | | /// thread::spawn(move || s2.send(20).unwrap()); |
832 | | /// |
833 | | /// let mut sel = Select::new(); |
834 | | /// let oper1 = sel.recv(&r1); |
835 | | /// let oper2 = sel.recv(&r2); |
836 | | /// |
837 | | /// // The second operation will be selected because it becomes ready first. |
838 | | /// let oper = sel.select_timeout(Duration::from_millis(500)); |
839 | | /// match oper { |
840 | | /// Err(_) => panic!("should not have timed out"), |
841 | | /// Ok(oper) => match oper.index() { |
842 | | /// i if i == oper1 => assert_eq!(oper.recv(&r1), Ok(10)), |
843 | | /// i if i == oper2 => assert_eq!(oper.recv(&r2), Ok(20)), |
844 | | /// _ => unreachable!(), |
845 | | /// } |
846 | | /// } |
847 | | /// ``` |
848 | 200k | pub fn select_timeout( |
849 | 200k | &mut self, |
850 | 200k | timeout: Duration, |
851 | 200k | ) -> Result<SelectedOperation<'a>, SelectTimeoutError> { |
852 | 200k | select_timeout(&mut self.handles, timeout) |
853 | 200k | } |
854 | | |
855 | | /// Blocks until a given deadline, or until one of the operations becomes ready and selects it. |
856 | | /// |
857 | | /// If an operation becomes ready, it is selected and returned. If multiple operations are |
858 | | /// ready at the same time, a random one among them is selected. If none of the operations |
859 | | /// become ready before the given deadline, an error is returned. |
860 | | /// |
861 | | /// An operation is considered to be ready if it doesn't have to block. Note that it is ready |
862 | | /// even when it will simply return an error because the channel is disconnected. |
863 | | /// |
864 | | /// The selected operation must be completed with [`SelectedOperation::send`] |
865 | | /// or [`SelectedOperation::recv`]. |
866 | | /// |
867 | | /// [`SelectedOperation::send`]: struct.SelectedOperation.html#method.send |
868 | | /// [`SelectedOperation::recv`]: struct.SelectedOperation.html#method.recv |
869 | | /// |
870 | | /// # Examples |
871 | | /// |
872 | | /// ``` |
873 | | /// use std::thread; |
874 | | /// use std::time::{Instant, Duration}; |
875 | | /// use crossbeam_channel::{unbounded, Select}; |
876 | | /// |
877 | | /// let (s1, r1) = unbounded(); |
878 | | /// let (s2, r2) = unbounded(); |
879 | | /// |
880 | | /// thread::spawn(move || { |
881 | | /// thread::sleep(Duration::from_secs(1)); |
882 | | /// s1.send(10).unwrap(); |
883 | | /// }); |
884 | | /// thread::spawn(move || s2.send(20).unwrap()); |
885 | | /// |
886 | | /// let mut sel = Select::new(); |
887 | | /// let oper1 = sel.recv(&r1); |
888 | | /// let oper2 = sel.recv(&r2); |
889 | | /// |
890 | | /// let deadline = Instant::now() + Duration::from_millis(500); |
891 | | /// |
892 | | /// // The second operation will be selected because it becomes ready first. |
893 | | /// let oper = sel.select_deadline(deadline); |
894 | | /// match oper { |
895 | | /// Err(_) => panic!("should not have timed out"), |
896 | | /// Ok(oper) => match oper.index() { |
897 | | /// i if i == oper1 => assert_eq!(oper.recv(&r1), Ok(10)), |
898 | | /// i if i == oper2 => assert_eq!(oper.recv(&r2), Ok(20)), |
899 | | /// _ => unreachable!(), |
900 | | /// } |
901 | | /// } |
902 | | /// ``` |
903 | | pub fn select_deadline( |
904 | | &mut self, |
905 | | deadline: Instant, |
906 | | ) -> Result<SelectedOperation<'a>, SelectTimeoutError> { |
907 | | select_deadline(&mut self.handles, deadline) |
908 | | } |
909 | | |
910 | | /// Attempts to find a ready operation without blocking. |
911 | | /// |
912 | | /// If an operation is ready, its index is returned. If multiple operations are ready at the |
913 | | /// same time, a random one among them is chosen. If none of the operations are ready, an error |
914 | | /// is returned. |
915 | | /// |
916 | | /// An operation is considered to be ready if it doesn't have to block. Note that it is ready |
917 | | /// even when it will simply return an error because the channel is disconnected. |
918 | | /// |
919 | | /// Note that this method might return with success spuriously, so it's a good idea to always |
920 | | /// double check if the operation is really ready. |
921 | | /// |
922 | | /// # Examples |
923 | | /// |
924 | | /// ``` |
925 | | /// use crossbeam_channel::{unbounded, Select}; |
926 | | /// |
927 | | /// let (s1, r1) = unbounded(); |
928 | | /// let (s2, r2) = unbounded(); |
929 | | /// |
930 | | /// s1.send(10).unwrap(); |
931 | | /// s2.send(20).unwrap(); |
932 | | /// |
933 | | /// let mut sel = Select::new(); |
934 | | /// let oper1 = sel.recv(&r1); |
935 | | /// let oper2 = sel.recv(&r2); |
936 | | /// |
937 | | /// // Both operations are initially ready, so a random one will be chosen. |
938 | | /// match sel.try_ready() { |
939 | | /// Err(_) => panic!("both operations should be ready"), |
940 | | /// Ok(i) if i == oper1 => assert_eq!(r1.try_recv(), Ok(10)), |
941 | | /// Ok(i) if i == oper2 => assert_eq!(r2.try_recv(), Ok(20)), |
942 | | /// Ok(_) => unreachable!(), |
943 | | /// } |
944 | | /// ``` |
945 | 9 | pub fn try_ready(&mut self) -> Result<usize, TryReadyError> { |
946 | 9 | match run_ready(&mut self.handles, Timeout::Now) { |
947 | 9 | None => Err(TryReadyError)4 , |
948 | 5 | Some(index) => Ok(index), |
949 | | } |
950 | 9 | } |
951 | | |
952 | | /// Blocks until one of the operations becomes ready. |
953 | | /// |
954 | | /// Once an operation becomes ready, its index is returned. If multiple operations are ready at |
955 | | /// the same time, a random one among them is chosen. |
956 | | /// |
957 | | /// An operation is considered to be ready if it doesn't have to block. Note that it is ready |
958 | | /// even when it will simply return an error because the channel is disconnected. |
959 | | /// |
960 | | /// Note that this method might return with success spuriously, so it's a good idea to always |
961 | | /// double check if the operation is really ready. |
962 | | /// |
963 | | /// # Panics |
964 | | /// |
965 | | /// Panics if no operations have been added to `Select`. |
966 | | /// |
967 | | /// # Examples |
968 | | /// |
969 | | /// ``` |
970 | | /// use std::thread; |
971 | | /// use std::time::Duration; |
972 | | /// use crossbeam_channel::{unbounded, Select}; |
973 | | /// |
974 | | /// let (s1, r1) = unbounded(); |
975 | | /// let (s2, r2) = unbounded(); |
976 | | /// |
977 | | /// thread::spawn(move || { |
978 | | /// thread::sleep(Duration::from_secs(1)); |
979 | | /// s1.send(10).unwrap(); |
980 | | /// }); |
981 | | /// thread::spawn(move || s2.send(20).unwrap()); |
982 | | /// |
983 | | /// let mut sel = Select::new(); |
984 | | /// let oper1 = sel.recv(&r1); |
985 | | /// let oper2 = sel.recv(&r2); |
986 | | /// |
987 | | /// // The second operation will be selected because it becomes ready first. |
988 | | /// match sel.ready() { |
989 | | /// i if i == oper1 => assert_eq!(r1.try_recv(), Ok(10)), |
990 | | /// i if i == oper2 => assert_eq!(r2.try_recv(), Ok(20)), |
991 | | /// _ => unreachable!(), |
992 | | /// } |
993 | | /// ``` |
994 | 175k | pub fn ready(&mut self) -> usize { |
995 | 175k | if self.handles.is_empty() { |
996 | 0 | panic!("no operations have been added to `Select`"); |
997 | 175k | } |
998 | 175k | |
999 | 175k | run_ready(&mut self.handles, Timeout::Never).unwrap() |
1000 | 175k | } |
1001 | | |
1002 | | /// Blocks for a limited time until one of the operations becomes ready. |
1003 | | /// |
1004 | | /// If an operation becomes ready, its index is returned. If multiple operations are ready at |
1005 | | /// the same time, a random one among them is chosen. If none of the operations become ready |
1006 | | /// for the specified duration, an error is returned. |
1007 | | /// |
1008 | | /// An operation is considered to be ready if it doesn't have to block. Note that it is ready |
1009 | | /// even when it will simply return an error because the channel is disconnected. |
1010 | | /// |
1011 | | /// Note that this method might return with success spuriously, so it's a good idea to double |
1012 | | /// check if the operation is really ready. |
1013 | | /// |
1014 | | /// # Examples |
1015 | | /// |
1016 | | /// ``` |
1017 | | /// use std::thread; |
1018 | | /// use std::time::Duration; |
1019 | | /// use crossbeam_channel::{unbounded, Select}; |
1020 | | /// |
1021 | | /// let (s1, r1) = unbounded(); |
1022 | | /// let (s2, r2) = unbounded(); |
1023 | | /// |
1024 | | /// thread::spawn(move || { |
1025 | | /// thread::sleep(Duration::from_secs(1)); |
1026 | | /// s1.send(10).unwrap(); |
1027 | | /// }); |
1028 | | /// thread::spawn(move || s2.send(20).unwrap()); |
1029 | | /// |
1030 | | /// let mut sel = Select::new(); |
1031 | | /// let oper1 = sel.recv(&r1); |
1032 | | /// let oper2 = sel.recv(&r2); |
1033 | | /// |
1034 | | /// // The second operation will be selected because it becomes ready first. |
1035 | | /// match sel.ready_timeout(Duration::from_millis(500)) { |
1036 | | /// Err(_) => panic!("should not have timed out"), |
1037 | | /// Ok(i) if i == oper1 => assert_eq!(r1.try_recv(), Ok(10)), |
1038 | | /// Ok(i) if i == oper2 => assert_eq!(r2.try_recv(), Ok(20)), |
1039 | | /// Ok(_) => unreachable!(), |
1040 | | /// } |
1041 | | /// ``` |
1042 | 53 | pub fn ready_timeout(&mut self, timeout: Duration) -> Result<usize, ReadyTimeoutError> { |
1043 | 53 | self.ready_deadline(Instant::now() + timeout) |
1044 | 53 | } |
1045 | | |
1046 | | /// Blocks until a given deadline, or until one of the operations becomes ready. |
1047 | | /// |
1048 | | /// If an operation becomes ready, its index is returned. If multiple operations are ready at |
1049 | | /// the same time, a random one among them is chosen. If none of the operations become ready |
1050 | | /// before the deadline, an error is returned. |
1051 | | /// |
1052 | | /// An operation is considered to be ready if it doesn't have to block. Note that it is ready |
1053 | | /// even when it will simply return an error because the channel is disconnected. |
1054 | | /// |
1055 | | /// Note that this method might return with success spuriously, so it's a good idea to double |
1056 | | /// check if the operation is really ready. |
1057 | | /// |
1058 | | /// # Examples |
1059 | | /// |
1060 | | /// ``` |
1061 | | /// use std::thread; |
1062 | | /// use std::time::{Duration, Instant}; |
1063 | | /// use crossbeam_channel::{unbounded, Select}; |
1064 | | /// |
1065 | | /// let deadline = Instant::now() + Duration::from_millis(500); |
1066 | | /// |
1067 | | /// let (s1, r1) = unbounded(); |
1068 | | /// let (s2, r2) = unbounded(); |
1069 | | /// |
1070 | | /// thread::spawn(move || { |
1071 | | /// thread::sleep(Duration::from_secs(1)); |
1072 | | /// s1.send(10).unwrap(); |
1073 | | /// }); |
1074 | | /// thread::spawn(move || s2.send(20).unwrap()); |
1075 | | /// |
1076 | | /// let mut sel = Select::new(); |
1077 | | /// let oper1 = sel.recv(&r1); |
1078 | | /// let oper2 = sel.recv(&r2); |
1079 | | /// |
1080 | | /// // The second operation will be selected because it becomes ready first. |
1081 | | /// match sel.ready_deadline(deadline) { |
1082 | | /// Err(_) => panic!("should not have timed out"), |
1083 | | /// Ok(i) if i == oper1 => assert_eq!(r1.try_recv(), Ok(10)), |
1084 | | /// Ok(i) if i == oper2 => assert_eq!(r2.try_recv(), Ok(20)), |
1085 | | /// Ok(_) => unreachable!(), |
1086 | | /// } |
1087 | | /// ``` |
1088 | 51 | pub fn ready_deadline(&mut self, deadline: Instant) -> Result<usize, ReadyTimeoutError> { |
1089 | 51 | match run_ready(&mut self.handles, Timeout::At(deadline)) { |
1090 | 51 | None => Err(ReadyTimeoutError)2 , |
1091 | 49 | Some(index) => Ok(index), |
1092 | | } |
1093 | 51 | } |
1094 | | } |
1095 | | |
1096 | | impl<'a> Clone for Select<'a> { |
1097 | 40 | fn clone(&self) -> Select<'a> { |
1098 | 40 | Select { |
1099 | 40 | handles: self.handles.clone(), |
1100 | 40 | next_index: self.next_index, |
1101 | 40 | } |
1102 | 40 | } |
1103 | | } |
1104 | | |
1105 | | impl<'a> Default for Select<'a> { |
1106 | | fn default() -> Select<'a> { |
1107 | | Select::new() |
1108 | | } |
1109 | | } |
1110 | | |
1111 | | impl fmt::Debug for Select<'_> { |
1112 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1113 | 0 | f.pad("Select { .. }") |
1114 | 0 | } |
1115 | | } |
1116 | | |
1117 | | /// A selected operation that needs to be completed. |
1118 | | /// |
1119 | | /// To complete the operation, call [`send`] or [`recv`]. |
1120 | | /// |
1121 | | /// # Panics |
1122 | | /// |
1123 | | /// Forgetting to complete the operation is an error and might lead to deadlocks. If a |
1124 | | /// `SelectedOperation` is dropped without completion, a panic occurs. |
1125 | | /// |
1126 | | /// [`send`]: SelectedOperation::send |
1127 | | /// [`recv`]: SelectedOperation::recv |
1128 | | #[must_use] |
1129 | | pub struct SelectedOperation<'a> { |
1130 | | /// Token needed to complete the operation. |
1131 | | token: Token, |
1132 | | |
1133 | | /// The index of the selected operation. |
1134 | | index: usize, |
1135 | | |
1136 | | /// The address of the selected `Sender` or `Receiver`. |
1137 | | ptr: *const u8, |
1138 | | |
1139 | | /// Indicates that `Sender`s and `Receiver`s are borrowed. |
1140 | | _marker: PhantomData<&'a ()>, |
1141 | | } |
1142 | | |
1143 | | impl SelectedOperation<'_> { |
1144 | | /// Returns the index of the selected operation. |
1145 | | /// |
1146 | | /// # Examples |
1147 | | /// |
1148 | | /// ``` |
1149 | | /// use crossbeam_channel::{bounded, Select}; |
1150 | | /// |
1151 | | /// let (s1, r1) = bounded::<()>(0); |
1152 | | /// let (s2, r2) = bounded::<()>(0); |
1153 | | /// let (s3, r3) = bounded::<()>(1); |
1154 | | /// |
1155 | | /// let mut sel = Select::new(); |
1156 | | /// let oper1 = sel.send(&s1); |
1157 | | /// let oper2 = sel.recv(&r2); |
1158 | | /// let oper3 = sel.send(&s3); |
1159 | | /// |
1160 | | /// // Only the last operation is ready. |
1161 | | /// let oper = sel.select(); |
1162 | | /// assert_eq!(oper.index(), 2); |
1163 | | /// assert_eq!(oper.index(), oper3); |
1164 | | /// |
1165 | | /// // Complete the operation. |
1166 | | /// oper.send(&s3, ()).unwrap(); |
1167 | | /// ``` |
1168 | 2.25M | pub fn index(&self) -> usize { |
1169 | 2.25M | self.index |
1170 | 2.25M | } |
1171 | | |
1172 | | /// Completes the send operation. |
1173 | | /// |
1174 | | /// The passed [`Sender`] reference must be the same one that was used in [`Select::send`] |
1175 | | /// when the operation was added. |
1176 | | /// |
1177 | | /// # Panics |
1178 | | /// |
1179 | | /// Panics if an incorrect [`Sender`] reference is passed. |
1180 | | /// |
1181 | | /// # Examples |
1182 | | /// |
1183 | | /// ``` |
1184 | | /// use crossbeam_channel::{bounded, Select, SendError}; |
1185 | | /// |
1186 | | /// let (s, r) = bounded::<i32>(0); |
1187 | | /// drop(r); |
1188 | | /// |
1189 | | /// let mut sel = Select::new(); |
1190 | | /// let oper1 = sel.send(&s); |
1191 | | /// |
1192 | | /// let oper = sel.select(); |
1193 | | /// assert_eq!(oper.index(), oper1); |
1194 | | /// assert_eq!(oper.send(&s, 10), Err(SendError(10))); |
1195 | | /// ``` |
1196 | 298k | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { |
1197 | | assert!( |
1198 | 298k | s as *const Sender<T> as *const u8 == self.ptr, |
1199 | | "passed a sender that wasn't selected", |
1200 | | ); |
1201 | 298k | let res = unsafe { channel::write(s, &mut self.token, msg) }; |
1202 | 298k | mem::forget(self); |
1203 | 298k | res.map_err(SendError) |
1204 | 298k | } <crossbeam_channel::select::SelectedOperation>::send::<()> Line | Count | Source | 1196 | 19.9k | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 19.9k | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 19.9k | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 19.9k | mem::forget(self); | 1203 | 19.9k | res.map_err(SendError) | 1204 | 19.9k | } |
<crossbeam_channel::select::SelectedOperation>::send::<usize> Line | Count | Source | 1196 | 39.9k | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 39.9k | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 39.9k | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 39.9k | mem::forget(self); | 1203 | 39.9k | res.map_err(SendError) | 1204 | 39.9k | } |
<crossbeam_channel::select::SelectedOperation>::send::<()> Line | Count | Source | 1196 | 10.0k | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 10.0k | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 10.0k | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 10.0k | mem::forget(self); | 1203 | 10.0k | res.map_err(SendError) | 1204 | 10.0k | } |
<crossbeam_channel::select::SelectedOperation>::send::<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>> Line | Count | Source | 1196 | 3.00k | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 3.00k | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 3.00k | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 3.00k | mem::forget(self); | 1203 | 3.00k | res.map_err(SendError) | 1204 | 3.00k | } |
<crossbeam_channel::select::SelectedOperation>::send::<i32> Line | Count | Source | 1196 | 33 | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 33 | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 33 | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 33 | mem::forget(self); | 1203 | 33 | res.map_err(SendError) | 1204 | 33 | } |
<crossbeam_channel::select::SelectedOperation>::send::<()> Line | Count | Source | 1196 | 1 | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 1 | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 1 | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 1 | mem::forget(self); | 1203 | 1 | res.map_err(SendError) | 1204 | 1 | } |
<crossbeam_channel::select::SelectedOperation>::send::<i32> Line | Count | Source | 1196 | 1 | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 1 | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 1 | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 1 | mem::forget(self); | 1203 | 1 | res.map_err(SendError) | 1204 | 1 | } |
<crossbeam_channel::select::SelectedOperation>::send::<()> Line | Count | Source | 1196 | 1 | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 1 | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 1 | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 1 | mem::forget(self); | 1203 | 1 | res.map_err(SendError) | 1204 | 1 | } |
<crossbeam_channel::select::SelectedOperation>::send::<u32> Line | Count | Source | 1196 | 3 | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 3 | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 3 | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 3 | mem::forget(self); | 1203 | 3 | res.map_err(SendError) | 1204 | 3 | } |
<crossbeam_channel::select::SelectedOperation>::send::<i64> Line | Count | Source | 1196 | 2 | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 2 | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 2 | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 2 | mem::forget(self); | 1203 | 2 | res.map_err(SendError) | 1204 | 2 | } |
<crossbeam_channel::select::SelectedOperation>::send::<alloc::string::String> Line | Count | Source | 1196 | 2 | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 2 | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 2 | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 2 | mem::forget(self); | 1203 | 2 | res.map_err(SendError) | 1204 | 2 | } |
<crossbeam_channel::select::SelectedOperation>::send::<u8> Line | Count | Source | 1196 | 10.0k | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 10.0k | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 10.0k | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 10.0k | mem::forget(self); | 1203 | 10.0k | res.map_err(SendError) | 1204 | 10.0k | } |
<crossbeam_channel::select::SelectedOperation>::send::<i32> Line | Count | Source | 1196 | 61.9k | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 61.9k | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 61.9k | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 61.9k | mem::forget(self); | 1203 | 61.9k | res.map_err(SendError) | 1204 | 61.9k | } |
Unexecuted instantiation: <crossbeam_channel::select::SelectedOperation>::send::<alloc::boxed::Box<dyn core::any::Any>> <crossbeam_channel::select::SelectedOperation>::send::<bool> Line | Count | Source | 1196 | 2 | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 2 | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 2 | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 2 | mem::forget(self); | 1203 | 2 | res.map_err(SendError) | 1204 | 2 | } |
<crossbeam_channel::select::SelectedOperation>::send::<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>> Line | Count | Source | 1196 | 3.00k | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 3.00k | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 3.00k | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 3.00k | mem::forget(self); | 1203 | 3.00k | res.map_err(SendError) | 1204 | 3.00k | } |
<crossbeam_channel::select::SelectedOperation>::send::<usize> Line | Count | Source | 1196 | 30.0k | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 30.0k | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 30.0k | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 30.0k | mem::forget(self); | 1203 | 30.0k | res.map_err(SendError) | 1204 | 30.0k | } |
<crossbeam_channel::select::SelectedOperation>::send::<i32> Line | Count | Source | 1196 | 57 | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 57 | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 57 | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 57 | mem::forget(self); | 1203 | 57 | res.map_err(SendError) | 1204 | 57 | } |
<crossbeam_channel::select::SelectedOperation>::send::<()> Line | Count | Source | 1196 | 19.9k | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 19.9k | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 19.9k | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 19.9k | mem::forget(self); | 1203 | 19.9k | res.map_err(SendError) | 1204 | 19.9k | } |
<crossbeam_channel::select::SelectedOperation>::send::<i32> Line | Count | Source | 1196 | 1 | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 1 | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 1 | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 1 | mem::forget(self); | 1203 | 1 | res.map_err(SendError) | 1204 | 1 | } |
<crossbeam_channel::select::SelectedOperation>::send::<()> Line | Count | Source | 1196 | 100k | pub fn send<T>(mut self, s: &Sender<T>, msg: T) -> Result<(), SendError<T>> { | 1197 | | assert!( | 1198 | 100k | s as *const Sender<T> as *const u8 == self.ptr, | 1199 | | "passed a sender that wasn't selected", | 1200 | | ); | 1201 | 100k | let res = unsafe { channel::write(s, &mut self.token, msg) }; | 1202 | 100k | mem::forget(self); | 1203 | 100k | res.map_err(SendError) | 1204 | 100k | } |
|
1205 | | |
1206 | | /// Completes the receive operation. |
1207 | | /// |
1208 | | /// The passed [`Receiver`] reference must be the same one that was used in [`Select::recv`] |
1209 | | /// when the operation was added. |
1210 | | /// |
1211 | | /// # Panics |
1212 | | /// |
1213 | | /// Panics if an incorrect [`Receiver`] reference is passed. |
1214 | | /// |
1215 | | /// # Examples |
1216 | | /// |
1217 | | /// ``` |
1218 | | /// use crossbeam_channel::{bounded, Select, RecvError}; |
1219 | | /// |
1220 | | /// let (s, r) = bounded::<i32>(0); |
1221 | | /// drop(s); |
1222 | | /// |
1223 | | /// let mut sel = Select::new(); |
1224 | | /// let oper1 = sel.recv(&r); |
1225 | | /// |
1226 | | /// let oper = sel.select(); |
1227 | | /// assert_eq!(oper.index(), oper1); |
1228 | | /// assert_eq!(oper.recv(&r), Err(RecvError)); |
1229 | | /// ``` |
1230 | 1.25M | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { |
1231 | | assert!( |
1232 | 1.25M | r as *const Receiver<T> as *const u8 == self.ptr, |
1233 | | "passed a receiver that wasn't selected", |
1234 | | ); |
1235 | 1.25M | let res = unsafe { channel::read(r, &mut self.token) }; |
1236 | 1.25M | mem::forget(self); |
1237 | 1.25M | res.map_err(|_| RecvError1.02k ) <crossbeam_channel::select::SelectedOperation>::recv::<i32>::{closure#0} Line | Count | Source | 1237 | 7 | res.map_err(|_| RecvError) |
<crossbeam_channel::select::SelectedOperation>::recv::<()>::{closure#0} Line | Count | Source | 1237 | 21 | res.map_err(|_| RecvError) |
<crossbeam_channel::select::SelectedOperation>::recv::<i32>::{closure#0} Line | Count | Source | 1237 | 3 | res.map_err(|_| RecvError) |
<crossbeam_channel::select::SelectedOperation>::recv::<u8>::{closure#0} Line | Count | Source | 1237 | 1 | res.map_err(|_| RecvError) |
<crossbeam_channel::select::SelectedOperation>::recv::<i32>::{closure#0} Line | Count | Source | 1237 | 989 | res.map_err(|_| RecvError) |
<crossbeam_channel::select::SelectedOperation>::recv::<i32>::{closure#0} Line | Count | Source | 1237 | 6 | res.map_err(|_| RecvError) |
|
1238 | 1.25M | } <crossbeam_channel::select::SelectedOperation>::recv::<()> Line | Count | Source | 1230 | 19.9k | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { | 1231 | | assert!( | 1232 | 19.9k | r as *const Receiver<T> as *const u8 == self.ptr, | 1233 | | "passed a receiver that wasn't selected", | 1234 | | ); | 1235 | 19.9k | let res = unsafe { channel::read(r, &mut self.token) }; | 1236 | 19.9k | mem::forget(self); | 1237 | 19.9k | res.map_err(|_| RecvError) | 1238 | 19.9k | } |
<crossbeam_channel::select::SelectedOperation>::recv::<()> Line | Count | Source | 1230 | 14.9k | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { | 1231 | | assert!( | 1232 | 14.9k | r as *const Receiver<T> as *const u8 == self.ptr, | 1233 | | "passed a receiver that wasn't selected", | 1234 | | ); | 1235 | 14.9k | let res = unsafe { channel::read(r, &mut self.token) }; | 1236 | 14.9k | mem::forget(self); | 1237 | 14.9k | res.map_err(|_| RecvError) | 1238 | 14.9k | } |
<crossbeam_channel::select::SelectedOperation>::recv::<std::time::Instant> Line | Count | Source | 1230 | 5.08k | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { | 1231 | | assert!( | 1232 | 5.08k | r as *const Receiver<T> as *const u8 == self.ptr, | 1233 | | "passed a receiver that wasn't selected", | 1234 | | ); | 1235 | 5.08k | let res = unsafe { channel::read(r, &mut self.token) }; | 1236 | 5.08k | mem::forget(self); | 1237 | 5.08k | res.map_err(|_| RecvError) | 1238 | 5.08k | } |
<crossbeam_channel::select::SelectedOperation>::recv::<i32> Line | Count | Source | 1230 | 399k | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { | 1231 | | assert!( | 1232 | 399k | r as *const Receiver<T> as *const u8 == self.ptr, | 1233 | | "passed a receiver that wasn't selected", | 1234 | | ); | 1235 | 399k | let res = unsafe { channel::read(r, &mut self.token) }; | 1236 | 399k | mem::forget(self); | 1237 | 399k | res.map_err(|_| RecvError) | 1238 | 399k | } |
<crossbeam_channel::select::SelectedOperation>::recv::<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>> Line | Count | Source | 1230 | 3.00k | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { | 1231 | | assert!( | 1232 | 3.00k | r as *const Receiver<T> as *const u8 == self.ptr, | 1233 | | "passed a receiver that wasn't selected", | 1234 | | ); | 1235 | 3.00k | let res = unsafe { channel::read(r, &mut self.token) }; | 1236 | 3.00k | mem::forget(self); | 1237 | 3.00k | res.map_err(|_| RecvError) | 1238 | 3.00k | } |
<crossbeam_channel::select::SelectedOperation>::recv::<usize> Line | Count | Source | 1230 | 39.9k | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { | 1231 | | assert!( | 1232 | 39.9k | r as *const Receiver<T> as *const u8 == self.ptr, | 1233 | | "passed a receiver that wasn't selected", | 1234 | | ); | 1235 | 39.9k | let res = unsafe { channel::read(r, &mut self.token) }; | 1236 | 39.9k | mem::forget(self); | 1237 | 39.9k | res.map_err(|_| RecvError) | 1238 | 39.9k | } |
<crossbeam_channel::select::SelectedOperation>::recv::<i32> Line | Count | Source | 1230 | 10.0k | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { | 1231 | | assert!( | 1232 | 10.0k | r as *const Receiver<T> as *const u8 == self.ptr, | 1233 | | "passed a receiver that wasn't selected", | 1234 | | ); | 1235 | 10.0k | let res = unsafe { channel::read(r, &mut self.token) }; | 1236 | 10.0k | mem::forget(self); | 1237 | 10.0k | res.map_err(|_| RecvError) | 1238 | 10.0k | } |
<crossbeam_channel::select::SelectedOperation>::recv::<()> Line | Count | Source | 1230 | 1 | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { | 1231 | | assert!( | 1232 | 1 | r as *const Receiver<T> as *const u8 == self.ptr, | 1233 | | "passed a receiver that wasn't selected", | 1234 | | ); | 1235 | 1 | let res = unsafe { channel::read(r, &mut self.token) }; | 1236 | 1 | mem::forget(self); | 1237 | 1 | res.map_err(|_| RecvError) | 1238 | 1 | } |
<crossbeam_channel::select::SelectedOperation>::recv::<std::time::Instant> Line | Count | Source | 1230 | 4.96k | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { | 1231 | | assert!( | 1232 | 4.96k | r as *const Receiver<T> as *const u8 == self.ptr, | 1233 | | "passed a receiver that wasn't selected", | 1234 | | ); | 1235 | 4.96k | let res = unsafe { channel::read(r, &mut self.token) }; | 1236 | 4.96k | mem::forget(self); | 1237 | 4.96k | res.map_err(|_| RecvError) | 1238 | 4.96k | } |
<crossbeam_channel::select::SelectedOperation>::recv::<()> Line | Count | Source | 1230 | 19.8k | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { | 1231 | | assert!( | 1232 | 19.8k | r as *const Receiver<T> as *const u8 == self.ptr, | 1233 | | "passed a receiver that wasn't selected", | 1234 | | ); | 1235 | 19.8k | let res = unsafe { channel::read(r, &mut self.token) }; | 1236 | 19.8k | mem::forget(self); | 1237 | 19.8k | res.map_err(|_| RecvError) | 1238 | 19.8k | } |
<crossbeam_channel::select::SelectedOperation>::recv::<std::time::Instant> Line | Count | Source | 1230 | 3.59k | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { | 1231 | | assert!( | 1232 | 3.59k | r as *const Receiver<T> as *const u8 == self.ptr, | 1233 | | "passed a receiver that wasn't selected", | 1234 | | ); | 1235 | 3.59k | let res = unsafe { channel::read(r, &mut self.token) }; | 1236 | 3.59k | mem::forget(self); | 1237 | 3.59k | res.map_err(|_| RecvError) | 1238 | 3.59k | } |
Unexecuted instantiation: <crossbeam_channel::select::SelectedOperation>::recv::<i32> <crossbeam_channel::select::SelectedOperation>::recv::<()> Line | Count | Source | 1230 | 19.8k | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { | 1231 | | assert!( | 1232 | 19.8k | r as *const Receiver<T> as *const u8 == self.ptr, | 1233 | | "passed a receiver that wasn't selected", | 1234 | | ); | 1235 | 19.8k | let res = unsafe { channel::read(r, &mut self.token) }; | 1236 | 19.8k | mem::forget(self); | 1237 | 19.8k | res.map_err(|_| RecvError) | 1238 | 19.8k | } |
<crossbeam_channel::select::SelectedOperation>::recv::<i32> Line | Count | Source | 1230 | 243k | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { | 1231 | | assert!( | 1232 | 243k | r as *const Receiver<T> as *const u8 == self.ptr, | 1233 | | "passed a receiver that wasn't selected", | 1234 | | ); | 1235 | 243k | let res = unsafe { channel::read(r, &mut self.token) }; | 1236 | 243k | mem::forget(self); | 1237 | 243k | res.map_err(|_| RecvError) | 1238 | 243k | } |
<crossbeam_channel::select::SelectedOperation>::recv::<bool> Line | Count | Source | 1230 | 1 | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { | 1231 | | assert!( | 1232 | 1 | r as *const Receiver<T> as *const u8 == self.ptr, | 1233 | | "passed a receiver that wasn't selected", | 1234 | | ); | 1235 | 1 | let res = unsafe { channel::read(r, &mut self.token) }; | 1236 | 1 | mem::forget(self); | 1237 | 1 | res.map_err(|_| RecvError) | 1238 | 1 | } |
<crossbeam_channel::select::SelectedOperation>::recv::<u8> Line | Count | Source | 1230 | 10.0k | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { | 1231 | | assert!( | 1232 | 10.0k | r as *const Receiver<T> as *const u8 == self.ptr, | 1233 | | "passed a receiver that wasn't selected", | 1234 | | ); | 1235 | 10.0k | let res = unsafe { channel::read(r, &mut self.token) }; | 1236 | 10.0k | mem::forget(self); | 1237 | 10.0k | res.map_err(|_| RecvError) | 1238 | 10.0k | } |
<crossbeam_channel::select::SelectedOperation>::recv::<usize> Line | Count | Source | 1230 | 30.0k | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { | 1231 | | assert!( | 1232 | 30.0k | r as *const Receiver<T> as *const u8 == self.ptr, | 1233 | | "passed a receiver that wasn't selected", | 1234 | | ); | 1235 | 30.0k | let res = unsafe { channel::read(r, &mut self.token) }; | 1236 | 30.0k | mem::forget(self); | 1237 | 30.0k | res.map_err(|_| RecvError) | 1238 | 30.0k | } |
<crossbeam_channel::select::SelectedOperation>::recv::<std::time::Instant> Line | Count | Source | 1230 | 5.08k | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { | 1231 | | assert!( | 1232 | 5.08k | r as *const Receiver<T> as *const u8 == self.ptr, | 1233 | | "passed a receiver that wasn't selected", | 1234 | | ); | 1235 | 5.08k | let res = unsafe { channel::read(r, &mut self.token) }; | 1236 | 5.08k | mem::forget(self); | 1237 | 5.08k | res.map_err(|_| RecvError) | 1238 | 5.08k | } |
<crossbeam_channel::select::SelectedOperation>::recv::<i32> Line | Count | Source | 1230 | 399k | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { | 1231 | | assert!( | 1232 | 399k | r as *const Receiver<T> as *const u8 == self.ptr, | 1233 | | "passed a receiver that wasn't selected", | 1234 | | ); | 1235 | 399k | let res = unsafe { channel::read(r, &mut self.token) }; | 1236 | 399k | mem::forget(self); | 1237 | 399k | res.map_err(|_| RecvError) | 1238 | 399k | } |
<crossbeam_channel::select::SelectedOperation>::recv::<()> Line | Count | Source | 1230 | 24.6k | pub fn recv<T>(mut self, r: &Receiver<T>) -> Result<T, RecvError> { | 1231 | | assert!( | 1232 | 24.6k | r as *const Receiver<T> as *const u8 == self.ptr, | 1233 | | "passed a receiver that wasn't selected", | 1234 | | ); | 1235 | 24.6k | let res = unsafe { channel::read(r, &mut self.token) }; | 1236 | 24.6k | mem::forget(self); | 1237 | 24.6k | res.map_err(|_| RecvError) | 1238 | 24.6k | } |
|
1239 | | } |
1240 | | |
1241 | | impl fmt::Debug for SelectedOperation<'_> { |
1242 | | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1243 | | f.pad("SelectedOperation { .. }") |
1244 | | } |
1245 | | } |
1246 | | |
1247 | | impl Drop for SelectedOperation<'_> { |
1248 | | fn drop(&mut self) { |
1249 | | panic!("dropped `SelectedOperation` without completing the operation"); |
1250 | | } |
1251 | | } |