/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 | | } |