Coverage Report

Created: 2021-01-22 16:54

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, PartialE
q12.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, PartialE
q55.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
}