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