Coverage Report

Created: 2025-05-07 06:59

/rust/registry/src/index.crates.io-6f17d22bba15001f/mio-1.0.3/src/waker.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{sys, Registry, Token};
2
3
use std::io;
4
5
/// Waker allows cross-thread waking of [`Poll`].
6
///
7
/// When created it will cause events with [`readable`] readiness and the
8
/// provided `token` if [`wake`] is called, possibly from another thread.
9
///
10
/// [`Poll`]: struct.Poll.html
11
/// [`readable`]: ./event/struct.Event.html#method.is_readable
12
/// [`wake`]: struct.Waker.html#method.wake
13
///
14
/// # Notes
15
///
16
/// `Waker` events are only guaranteed to be delivered while the `Waker` value
17
/// is alive.
18
///
19
/// Only a single `Waker` can be active per [`Poll`], if multiple threads need
20
/// access to the `Waker` it can be shared via for example an `Arc`. What
21
/// happens if multiple `Waker`s are registered with the same `Poll` is
22
/// unspecified.
23
///
24
/// # Implementation notes
25
///
26
/// On platforms that support kqueue this will use the `EVFILT_USER` event
27
/// filter, see [implementation notes of `Poll`] to see what platforms support
28
/// kqueue. On Linux it uses [eventfd].
29
///
30
/// [implementation notes of `Poll`]: struct.Poll.html#implementation-notes
31
/// [eventfd]: https://man7.org/linux/man-pages/man2/eventfd.2.html
32
///
33
/// # Examples
34
///
35
/// Wake a [`Poll`] instance from another thread.
36
///
37
#[cfg_attr(feature = "os-poll", doc = "```")]
38
#[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
39
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
40
/// use std::thread;
41
/// use std::time::Duration;
42
/// use std::sync::Arc;
43
///
44
/// use mio::{Events, Token, Poll, Waker};
45
///
46
/// const WAKE_TOKEN: Token = Token(10);
47
///
48
/// let mut poll = Poll::new()?;
49
/// let mut events = Events::with_capacity(2);
50
///
51
/// let waker = Arc::new(Waker::new(poll.registry(), WAKE_TOKEN)?);
52
///
53
/// // We need to keep the Waker alive, so we'll create a clone for the
54
/// // thread we create below.
55
/// let waker1 = waker.clone();
56
/// let handle = thread::spawn(move || {
57
///     // Working hard, or hardly working?
58
///     thread::sleep(Duration::from_millis(500));
59
///
60
///     // Now we'll wake the queue on the other thread.
61
///     waker1.wake().expect("unable to wake");
62
/// });
63
///
64
/// // On our current thread we'll poll for events, without a timeout.
65
/// poll.poll(&mut events, None)?;
66
///
67
/// // After about 500 milliseconds we should be awoken by the other thread and
68
/// // get a single event.
69
/// assert!(!events.is_empty());
70
/// let waker_event = events.iter().next().unwrap();
71
/// assert!(waker_event.is_readable());
72
/// assert_eq!(waker_event.token(), WAKE_TOKEN);
73
/// # handle.join().unwrap();
74
/// #     Ok(())
75
/// # }
76
/// ```
77
#[derive(Debug)]
78
pub struct Waker {
79
    inner: sys::Waker,
80
}
81
82
impl Waker {
83
    /// Create a new `Waker`.
84
0
    pub fn new(registry: &Registry, token: Token) -> io::Result<Waker> {
85
0
        #[cfg(debug_assertions)]
86
0
        registry.register_waker();
87
0
        sys::Waker::new(registry.selector(), token).map(|inner| Waker { inner })
88
0
    }
89
90
    /// Wake up the [`Poll`] associated with this `Waker`.
91
    ///
92
    /// [`Poll`]: struct.Poll.html
93
0
    pub fn wake(&self) -> io::Result<()> {
94
0
        self.inner.wake()
95
0
    }
96
}