1 use std::io;
2 #[cfg(not(target_os = "hermit"))]
3 use std::os::fd::RawFd;
4 // TODO: once <https://github.com/rust-lang/rust/issues/126198> is fixed this
5 // can use `std::os::fd` and be merged with the above.
6 #[cfg(target_os = "hermit")]
7 use std::os::hermit::io::RawFd;
8 
9 use crate::{event, Interest, Registry, Token};
10 
11 /// Adapter for [`RawFd`] providing an [`event::Source`] implementation.
12 ///
13 /// `SourceFd` enables registering any type with an FD with [`Poll`].
14 ///
15 /// While only implementations for TCP and UDP are provided, Mio supports
16 /// registering any FD that can be registered with the underlying OS selector.
17 /// `SourceFd` provides the necessary bridge.
18 ///
19 /// Note that `SourceFd` takes a `&RawFd`. This is because `SourceFd` **does
20 /// not** take ownership of the FD. Specifically, it will not manage any
21 /// lifecycle related operations, such as closing the FD on drop. It is expected
22 /// that the `SourceFd` is constructed right before a call to
23 /// [`Registry::register`]. See the examples for more detail.
24 ///
25 /// [`event::Source`]: ../event/trait.Source.html
26 /// [`Poll`]: ../struct.Poll.html
27 /// [`Registry::register`]: ../struct.Registry.html#method.register
28 ///
29 /// # Examples
30 ///
31 /// Basic usage.
32 ///
33 #[cfg_attr(
34     all(feature = "os-poll", feature = "net", feature = "os-ext"),
35     doc = "```"
36 )]
37 #[cfg_attr(
38     not(all(feature = "os-poll", feature = "net", feature = "os-ext")),
39     doc = "```ignore"
40 )]
41 /// # use std::error::Error;
42 /// # fn main() -> Result<(), Box<dyn Error>> {
43 /// use mio::{Interest, Poll, Token};
44 /// use mio::unix::SourceFd;
45 ///
46 /// use std::os::fd::AsRawFd;
47 /// use std::net::TcpListener;
48 ///
49 /// // Bind a std listener
50 /// let listener = TcpListener::bind("127.0.0.1:0")?;
51 ///
52 /// let poll = Poll::new()?;
53 ///
54 /// // Register the listener
55 /// poll.registry().register(
56 ///     &mut SourceFd(&listener.as_raw_fd()),
57 ///     Token(0),
58 ///     Interest::READABLE)?;
59 /// #     Ok(())
60 /// # }
61 /// ```
62 ///
63 /// Implementing [`event::Source`] for a custom type backed by a [`RawFd`].
64 ///
65 #[cfg_attr(all(feature = "os-poll", feature = "os-ext"), doc = "```")]
66 #[cfg_attr(not(all(feature = "os-poll", feature = "os-ext")), doc = "```ignore")]
67 /// use mio::{event, Interest, Registry, Token};
68 /// use mio::unix::SourceFd;
69 ///
70 /// use std::os::fd::RawFd;
71 /// use std::io;
72 ///
73 /// # #[allow(dead_code)]
74 /// pub struct MyIo {
75 ///     fd: RawFd,
76 /// }
77 ///
78 /// impl event::Source for MyIo {
79 ///     fn register(&mut self, registry: &Registry, token: Token, interests: Interest)
80 ///         -> io::Result<()>
81 ///     {
82 ///         SourceFd(&self.fd).register(registry, token, interests)
83 ///     }
84 ///
85 ///     fn reregister(&mut self, registry: &Registry, token: Token, interests: Interest)
86 ///         -> io::Result<()>
87 ///     {
88 ///         SourceFd(&self.fd).reregister(registry, token, interests)
89 ///     }
90 ///
91 ///     fn deregister(&mut self, registry: &Registry) -> io::Result<()> {
92 ///         SourceFd(&self.fd).deregister(registry)
93 ///     }
94 /// }
95 /// ```
96 #[derive(Debug)]
97 pub struct SourceFd<'a>(pub &'a RawFd);
98 
99 impl<'a> event::Source for SourceFd<'a> {
register( &mut self, registry: &Registry, token: Token, interests: Interest, ) -> io::Result<()>100     fn register(
101         &mut self,
102         registry: &Registry,
103         token: Token,
104         interests: Interest,
105     ) -> io::Result<()> {
106         registry.selector().register(*self.0, token, interests)
107     }
108 
reregister( &mut self, registry: &Registry, token: Token, interests: Interest, ) -> io::Result<()>109     fn reregister(
110         &mut self,
111         registry: &Registry,
112         token: Token,
113         interests: Interest,
114     ) -> io::Result<()> {
115         registry.selector().reregister(*self.0, token, interests)
116     }
117 
deregister(&mut self, registry: &Registry) -> io::Result<()>118     fn deregister(&mut self, registry: &Registry) -> io::Result<()> {
119         registry.selector().deregister(*self.0)
120     }
121 }
122