mio/sys/unix/
sourcefd.rs

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