1 #[cfg(all(
2     unix,
3     not(mio_unsupported_force_poll_poll),
4     not(any(
5         target_os = "aix",
6         target_os = "espidf",
7         target_os = "fuchsia",
8         target_os = "haiku",
9         target_os = "hermit",
10         target_os = "hurd",
11         target_os = "nto",
12         target_os = "solaris",
13         target_os = "vita"
14     )),
15 ))]
16 use std::os::fd::{AsRawFd, RawFd};
17 #[cfg(all(debug_assertions, not(target_os = "wasi")))]
18 use std::sync::atomic::{AtomicBool, Ordering};
19 #[cfg(all(debug_assertions, not(target_os = "wasi")))]
20 use std::sync::Arc;
21 use std::time::Duration;
22 use std::{fmt, io};
23 
24 use crate::{event, sys, Events, Interest, Token};
25 
26 /// Polls for readiness events on all registered values.
27 ///
28 /// `Poll` allows a program to monitor a large number of [`event::Source`]s,
29 /// waiting until one or more become "ready" for some class of operations; e.g.
30 /// reading and writing. An event source is considered ready if it is possible
31 /// to immediately perform a corresponding operation; e.g. [`read`] or
32 /// [`write`].
33 ///
34 /// To use `Poll`, an `event::Source` must first be registered with the `Poll`
35 /// instance using the [`register`] method on its associated `Register`,
36 /// supplying readiness interest. The readiness interest tells `Poll` which
37 /// specific operations on the handle to monitor for readiness. A `Token` is
38 /// also passed to the [`register`] function. When `Poll` returns a readiness
39 /// event, it will include this token.  This associates the event with the
40 /// event source that generated the event.
41 ///
42 /// [`event::Source`]: ./event/trait.Source.html
43 /// [`read`]: ./net/struct.TcpStream.html#method.read
44 /// [`write`]: ./net/struct.TcpStream.html#method.write
45 /// [`register`]: struct.Registry.html#method.register
46 ///
47 /// # Examples
48 ///
49 /// A basic example -- establishing a `TcpStream` connection.
50 ///
51 #[cfg_attr(all(feature = "os-poll", feature = "net"), doc = "```")]
52 #[cfg_attr(not(all(feature = "os-poll", feature = "net")), doc = "```ignore")]
53 /// # use std::error::Error;
54 /// # fn main() -> Result<(), Box<dyn Error>> {
55 /// use mio::{Events, Poll, Interest, Token};
56 /// use mio::net::TcpStream;
57 ///
58 /// use std::net::{self, SocketAddr};
59 ///
60 /// // Bind a server socket to connect to.
61 /// let addr: SocketAddr = "127.0.0.1:0".parse()?;
62 /// let server = net::TcpListener::bind(addr)?;
63 ///
64 /// // Construct a new `Poll` handle as well as the `Events` we'll store into
65 /// let mut poll = Poll::new()?;
66 /// let mut events = Events::with_capacity(1024);
67 ///
68 /// // Connect the stream
69 /// let mut stream = TcpStream::connect(server.local_addr()?)?;
70 ///
71 /// // Register the stream with `Poll`
72 /// poll.registry().register(&mut stream, Token(0), Interest::READABLE | Interest::WRITABLE)?;
73 ///
74 /// // Wait for the socket to become ready. This has to happens in a loop to
75 /// // handle spurious wakeups.
76 /// loop {
77 ///     poll.poll(&mut events, None)?;
78 ///
79 ///     for event in &events {
80 ///         if event.token() == Token(0) && event.is_writable() {
81 ///             // The socket connected (probably, it could still be a spurious
82 ///             // wakeup)
83 ///             return Ok(());
84 ///         }
85 ///     }
86 /// }
87 /// # }
88 /// ```
89 ///
90 /// # Portability
91 ///
92 /// Using `Poll` provides a portable interface across supported platforms as
93 /// long as the caller takes the following into consideration:
94 ///
95 /// ### Spurious events
96 ///
97 /// [`Poll::poll`] may return readiness events even if the associated
98 /// event source is not actually ready. Given the same code, this may
99 /// happen more on some platforms than others. It is important to never assume
100 /// that, just because a readiness event was received, that the associated
101 /// operation will succeed as well.
102 ///
103 /// If operation fails with [`WouldBlock`], then the caller should not treat
104 /// this as an error, but instead should wait until another readiness event is
105 /// received.
106 ///
107 /// ### Draining readiness
108 ///
109 /// Once a readiness event is received, the corresponding operation must be
110 /// performed repeatedly until it returns [`WouldBlock`]. Unless this is done,
111 /// there is no guarantee that another readiness event will be delivered, even
112 /// if further data is received for the event source.
113 ///
114 /// [`WouldBlock`]: std::io::ErrorKind::WouldBlock
115 ///
116 /// ### Readiness operations
117 ///
118 /// The only readiness operations that are guaranteed to be present on all
119 /// supported platforms are [`readable`] and [`writable`]. All other readiness
120 /// operations may have false negatives and as such should be considered
121 /// **hints**. This means that if a socket is registered with [`readable`]
122 /// interest and either an error or close is received, a readiness event will
123 /// be generated for the socket, but it **may** only include `readable`
124 /// readiness. Also note that, given the potential for spurious events,
125 /// receiving a readiness event with `read_closed`, `write_closed`, or `error`
126 /// doesn't actually mean that a `read` on the socket will return a result
127 /// matching the readiness event.
128 ///
129 /// In other words, portable programs that explicitly check for [`read_closed`],
130 /// [`write_closed`], or [`error`] readiness should be doing so as an
131 /// **optimization** and always be able to handle an error or close situation
132 /// when performing the actual read operation.
133 ///
134 /// [`readable`]: ./event/struct.Event.html#method.is_readable
135 /// [`writable`]: ./event/struct.Event.html#method.is_writable
136 /// [`error`]: ./event/struct.Event.html#method.is_error
137 /// [`read_closed`]: ./event/struct.Event.html#method.is_read_closed
138 /// [`write_closed`]: ./event/struct.Event.html#method.is_write_closed
139 ///
140 /// ### Registering handles
141 ///
142 /// Unless otherwise noted, it should be assumed that types implementing
143 /// [`event::Source`] will never become ready unless they are registered with
144 /// `Poll`.
145 ///
146 /// For example:
147 ///
148 #[cfg_attr(all(feature = "os-poll", feature = "net"), doc = "```")]
149 #[cfg_attr(not(all(feature = "os-poll", feature = "net")), doc = "```ignore")]
150 /// # use std::error::Error;
151 /// # use std::net;
152 /// # fn main() -> Result<(), Box<dyn Error>> {
153 /// use mio::{Poll, Interest, Token};
154 /// use mio::net::TcpStream;
155 /// use std::net::SocketAddr;
156 /// use std::time::Duration;
157 /// use std::thread;
158 ///
159 /// let address: SocketAddr = "127.0.0.1:0".parse()?;
160 /// let listener = net::TcpListener::bind(address)?;
161 /// let mut sock = TcpStream::connect(listener.local_addr()?)?;
162 ///
163 /// thread::sleep(Duration::from_secs(1));
164 ///
165 /// let poll = Poll::new()?;
166 ///
167 /// // The connect is not guaranteed to have started until it is registered at
168 /// // this point
169 /// poll.registry().register(&mut sock, Token(0), Interest::READABLE | Interest::WRITABLE)?;
170 /// #     Ok(())
171 /// # }
172 /// ```
173 ///
174 /// ### Dropping `Poll`
175 ///
176 /// When the `Poll` instance is dropped it may cancel in-flight operations for
177 /// the registered [event sources], meaning that no further events for them may
178 /// be received. It also means operations on the registered event sources may no
179 /// longer work. It is up to the user to keep the `Poll` instance alive while
180 /// registered event sources are being used.
181 ///
182 /// [event sources]: ./event/trait.Source.html
183 ///
184 /// ### Accessing raw fd/socket/handle
185 ///
186 /// Mio makes it possible for many types to be converted into a raw file
187 /// descriptor (fd, Unix), socket (Windows) or handle (Windows). This makes it
188 /// possible to support more operations on the type than Mio supports, for
189 /// example it makes [mio-aio] possible. However accessing the raw fd is not
190 /// without it's pitfalls.
191 ///
192 /// Specifically performing I/O operations outside of Mio on these types (via
193 /// the raw fd) has unspecified behaviour. It could cause no more events to be
194 /// generated for the type even though it returned `WouldBlock` (in an operation
195 /// directly accessing the fd). The behaviour is OS specific and Mio can only
196 /// guarantee cross-platform behaviour if it can control the I/O.
197 ///
198 /// [mio-aio]: https://github.com/asomers/mio-aio
199 ///
200 /// *The following is **not** guaranteed, just a description of the current
201 /// situation!* Mio is allowed to change the following without it being considered
202 /// a breaking change, don't depend on this, it's just here to inform the user.
203 /// Currently the kqueue and epoll implementation support direct I/O operations
204 /// on the fd without Mio's knowledge. Windows however needs **all** I/O
205 /// operations to go through Mio otherwise it is not able to update it's
206 /// internal state properly and won't generate events.
207 ///
208 /// ### Polling without registering event sources
209 ///
210 ///
211 /// *The following is **not** guaranteed, just a description of the current
212 /// situation!* Mio is allowed to change the following without it being
213 /// considered a breaking change, don't depend on this, it's just here to inform
214 /// the user. On platforms that use epoll, kqueue or IOCP (see implementation
215 /// notes below) polling without previously registering [event sources] will
216 /// result in sleeping forever, only a process signal will be able to wake up
217 /// the thread.
218 ///
219 /// On WASM/WASI this is different as it doesn't support process signals,
220 /// furthermore the WASI specification doesn't specify a behaviour in this
221 /// situation, thus it's up to the implementation what to do here. As an
222 /// example, the wasmtime runtime will return `EINVAL` in this situation, but
223 /// different runtimes may return different results. If you have further
224 /// insights or thoughts about this situation (and/or how Mio should handle it)
225 /// please add you comment to [pull request#1580].
226 ///
227 /// [event sources]: crate::event::Source
228 /// [pull request#1580]: https://github.com/tokio-rs/mio/pull/1580
229 ///
230 /// # Implementation notes
231 ///
232 /// `Poll` is backed by the selector provided by the operating system.
233 ///
234 /// |      OS       |  Selector |
235 /// |---------------|-----------|
236 /// | Android       | [epoll]   |
237 /// | DragonFly BSD | [kqueue]  |
238 /// | FreeBSD       | [kqueue]  |
239 /// | iOS           | [kqueue]  |
240 /// | illumos       | [epoll]   |
241 /// | Linux         | [epoll]   |
242 /// | NetBSD        | [kqueue]  |
243 /// | OpenBSD       | [kqueue]  |
244 /// | Windows       | [IOCP]    |
245 /// | macOS         | [kqueue]  |
246 ///
247 /// On all supported platforms, socket operations are handled by using the
248 /// system selector. Platform specific extensions (e.g. [`SourceFd`]) allow
249 /// accessing other features provided by individual system selectors. For
250 /// example, Linux's [`signalfd`] feature can be used by registering the FD with
251 /// `Poll` via [`SourceFd`].
252 ///
253 /// On all platforms except windows, a call to [`Poll::poll`] is mostly just a
254 /// direct call to the system selector. However, [IOCP] uses a completion model
255 /// instead of a readiness model. In this case, `Poll` must adapt the completion
256 /// model Mio's API. While non-trivial, the bridge layer is still quite
257 /// efficient. The most expensive part being calls to `read` and `write` require
258 /// data to be copied into an intermediate buffer before it is passed to the
259 /// kernel.
260 ///
261 /// [epoll]: https://man7.org/linux/man-pages/man7/epoll.7.html
262 /// [kqueue]: https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2
263 /// [IOCP]: https://docs.microsoft.com/en-us/windows/win32/fileio/i-o-completion-ports
264 /// [`signalfd`]: https://man7.org/linux/man-pages/man2/signalfd.2.html
265 /// [`SourceFd`]: unix/struct.SourceFd.html
266 /// [`Poll::poll`]: struct.Poll.html#method.poll
267 pub struct Poll {
268     registry: Registry,
269 }
270 
271 /// Registers I/O resources.
272 pub struct Registry {
273     selector: sys::Selector,
274     /// Whether this selector currently has an associated waker.
275     #[cfg(all(debug_assertions, not(target_os = "wasi")))]
276     has_waker: Arc<AtomicBool>,
277 }
278 
279 impl Poll {
280     cfg_os_poll! {
281         /// Return a new `Poll` handle.
282         ///
283         /// This function will make a syscall to the operating system to create
284         /// the system selector. If this syscall fails, `Poll::new` will return
285         /// with the error.
286         ///
287         /// close-on-exec flag is set on the file descriptors used by the selector to prevent
288         /// leaking it to executed processes. However, on some systems such as
289         /// old Linux systems that don't support `epoll_create1` syscall it is done
290         /// non-atomically, so a separate thread executing in parallel to this
291         /// function may accidentally leak the file descriptor if it executes a
292         /// new process before this function returns.
293         ///
294         /// See [struct] level docs for more details.
295         ///
296         /// [struct]: struct.Poll.html
297         ///
298         /// # Examples
299         ///
300         /// ```
301         /// # use std::error::Error;
302         /// # fn main() -> Result<(), Box<dyn Error>> {
303         /// use mio::{Poll, Events};
304         /// use std::time::Duration;
305         ///
306         /// let mut poll = match Poll::new() {
307         ///     Ok(poll) => poll,
308         ///     Err(e) => panic!("failed to create Poll instance; err={:?}", e),
309         /// };
310         ///
311         /// // Create a structure to receive polled events
312         /// let mut events = Events::with_capacity(1024);
313         ///
314         /// // Wait for events, but none will be received because no
315         /// // `event::Source`s have been registered with this `Poll` instance.
316         /// poll.poll(&mut events, Some(Duration::from_millis(500)))?;
317         /// assert!(events.is_empty());
318         /// #     Ok(())
319         /// # }
320         /// ```
321         pub fn new() -> io::Result<Poll> {
322             sys::Selector::new().map(|selector| Poll {
323                 registry: Registry {
324                     selector,
325                     #[cfg(all(debug_assertions, not(target_os = "wasi")))]
326                     has_waker: Arc::new(AtomicBool::new(false)),
327                 },
328             })
329         }
330     }
331 
332     /// Create a separate `Registry` which can be used to register
333     /// `event::Source`s.
registry(&self) -> &Registry334     pub fn registry(&self) -> &Registry {
335         &self.registry
336     }
337 
338     /// Wait for readiness events
339     ///
340     /// Blocks the current thread and waits for readiness events for any of the
341     /// [`event::Source`]s that have been registered with this `Poll` instance.
342     /// The function will block until either at least one readiness event has
343     /// been received or `timeout` has elapsed. A `timeout` of `None` means that
344     /// `poll` will block until a readiness event has been received.
345     ///
346     /// The supplied `events` will be cleared and newly received readiness events
347     /// will be pushed onto the end. At most `events.capacity()` events will be
348     /// returned. If there are further pending readiness events, they will be
349     /// returned on the next call to `poll`.
350     ///
351     /// A single call to `poll` may result in multiple readiness events being
352     /// returned for a single event source. For example, if a TCP socket becomes
353     /// both readable and writable, it may be possible for a single readiness
354     /// event to be returned with both [`readable`] and [`writable`] readiness
355     /// **OR** two separate events may be returned, one with [`readable`] set
356     /// and one with [`writable`] set.
357     ///
358     /// Note that the `timeout` will be rounded up to the system clock
359     /// granularity (usually 1ms), and kernel scheduling delays mean that
360     /// the blocking interval may be overrun by a small amount.
361     ///
362     /// See the [struct] level documentation for a higher level discussion of
363     /// polling.
364     ///
365     /// [`event::Source`]: ./event/trait.Source.html
366     /// [`readable`]: struct.Interest.html#associatedconstant.READABLE
367     /// [`writable`]: struct.Interest.html#associatedconstant.WRITABLE
368     /// [struct]: struct.Poll.html
369     /// [`iter`]: ./event/struct.Events.html#method.iter
370     ///
371     /// # Notes
372     ///
373     /// This returns any errors without attempting to retry, previous versions
374     /// of Mio would automatically retry the poll call if it was interrupted
375     /// (if `EINTR` was returned).
376     ///
377     /// Currently if the `timeout` elapses without any readiness events
378     /// triggering this will return `Ok(())`. However we're not guaranteeing
379     /// this behaviour as this depends on the OS.
380     ///
381     /// # Examples
382     ///
383     /// A basic example -- establishing a `TcpStream` connection.
384     ///
385     #[cfg_attr(all(feature = "os-poll", feature = "net"), doc = "```")]
386     #[cfg_attr(not(all(feature = "os-poll", feature = "net")), doc = "```ignore")]
387     /// # use std::error::Error;
388     /// # fn main() -> Result<(), Box<dyn Error>> {
389     /// use mio::{Events, Poll, Interest, Token};
390     /// use mio::net::TcpStream;
391     ///
392     /// use std::net::{TcpListener, SocketAddr};
393     /// use std::thread;
394     ///
395     /// // Bind a server socket to connect to.
396     /// let addr: SocketAddr = "127.0.0.1:0".parse()?;
397     /// let server = TcpListener::bind(addr)?;
398     /// let addr = server.local_addr()?.clone();
399     ///
400     /// // Spawn a thread to accept the socket
401     /// thread::spawn(move || {
402     ///     let _ = server.accept();
403     /// });
404     ///
405     /// // Construct a new `Poll` handle as well as the `Events` we'll store into
406     /// let mut poll = Poll::new()?;
407     /// let mut events = Events::with_capacity(1024);
408     ///
409     /// // Connect the stream
410     /// let mut stream = TcpStream::connect(addr)?;
411     ///
412     /// // Register the stream with `Poll`
413     /// poll.registry().register(
414     ///     &mut stream,
415     ///     Token(0),
416     ///     Interest::READABLE | Interest::WRITABLE)?;
417     ///
418     /// // Wait for the socket to become ready. This has to happens in a loop to
419     /// // handle spurious wakeups.
420     /// loop {
421     ///     poll.poll(&mut events, None)?;
422     ///
423     ///     for event in &events {
424     ///         if event.token() == Token(0) && event.is_writable() {
425     ///             // The socket connected (probably, it could still be a spurious
426     ///             // wakeup)
427     ///             return Ok(());
428     ///         }
429     ///     }
430     /// }
431     /// # }
432     /// ```
433     ///
434     /// [struct]: #
poll(&mut self, events: &mut Events, timeout: Option<Duration>) -> io::Result<()>435     pub fn poll(&mut self, events: &mut Events, timeout: Option<Duration>) -> io::Result<()> {
436         self.registry.selector.select(events.sys(), timeout)
437     }
438 }
439 
440 #[cfg(all(
441     unix,
442     not(mio_unsupported_force_poll_poll),
443     not(any(
444         target_os = "aix",
445         target_os = "espidf",
446         target_os = "fuchsia",
447         target_os = "haiku",
448         target_os = "hermit",
449         target_os = "hurd",
450         target_os = "nto",
451         target_os = "solaris",
452         target_os = "vita"
453     )),
454 ))]
455 impl AsRawFd for Poll {
as_raw_fd(&self) -> RawFd456     fn as_raw_fd(&self) -> RawFd {
457         self.registry.as_raw_fd()
458     }
459 }
460 
461 impl fmt::Debug for Poll {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result462     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
463         fmt.debug_struct("Poll").finish()
464     }
465 }
466 
467 impl Registry {
468     /// Register an [`event::Source`] with the `Poll` instance.
469     ///
470     /// Once registered, the `Poll` instance will monitor the event source for
471     /// readiness state changes. When it notices a state change, it will return
472     /// a readiness event for the handle the next time [`poll`] is called.
473     ///
474     /// See [`Poll`] docs for a high level overview.
475     ///
476     /// # Arguments
477     ///
478     /// `source: &mut S: event::Source`: This is the source of events that the
479     /// `Poll` instance should monitor for readiness state changes.
480     ///
481     /// `token: Token`: The caller picks a token to associate with the socket.
482     /// When [`poll`] returns an event for the handle, this token is included.
483     /// This allows the caller to map the event to its source. The token
484     /// associated with the `event::Source` can be changed at any time by
485     /// calling [`reregister`].
486     ///
487     /// See documentation on [`Token`] for an example showing how to pick
488     /// [`Token`] values.
489     ///
490     /// `interest: Interest`: Specifies which operations `Poll` should monitor
491     /// for readiness. `Poll` will only return readiness events for operations
492     /// specified by this argument.
493     ///
494     /// If a socket is registered with readable interest and the socket becomes
495     /// writable, no event will be returned from [`poll`].
496     ///
497     /// The readiness interest for an `event::Source` can be changed at any time
498     /// by calling [`reregister`].
499     ///
500     /// # Notes
501     ///
502     /// Callers must ensure that if a source being registered with a `Poll`
503     /// instance was previously registered with that `Poll` instance, then a
504     /// call to [`deregister`] has already occurred. Consecutive calls to
505     /// `register` is unspecified behavior.
506     ///
507     /// Unless otherwise specified, the caller should assume that once an event
508     /// source is registered with a `Poll` instance, it is bound to that `Poll`
509     /// instance for the lifetime of the event source. This remains true even
510     /// if the event source is deregistered from the poll instance using
511     /// [`deregister`].
512     ///
513     /// [`event::Source`]: ./event/trait.Source.html
514     /// [`poll`]: struct.Poll.html#method.poll
515     /// [`reregister`]: struct.Registry.html#method.reregister
516     /// [`deregister`]: struct.Registry.html#method.deregister
517     /// [`Token`]: struct.Token.html
518     ///
519     /// # Examples
520     ///
521     #[cfg_attr(all(feature = "os-poll", feature = "net"), doc = "```")]
522     #[cfg_attr(not(all(feature = "os-poll", feature = "net")), doc = "```ignore")]
523     /// # use std::error::Error;
524     /// # use std::net;
525     /// # fn main() -> Result<(), Box<dyn Error>> {
526     /// use mio::{Events, Poll, Interest, Token};
527     /// use mio::net::TcpStream;
528     /// use std::net::SocketAddr;
529     /// use std::time::{Duration, Instant};
530     ///
531     /// let mut poll = Poll::new()?;
532     ///
533     /// let address: SocketAddr = "127.0.0.1:0".parse()?;
534     /// let listener = net::TcpListener::bind(address)?;
535     /// let mut socket = TcpStream::connect(listener.local_addr()?)?;
536     ///
537     /// // Register the socket with `poll`
538     /// poll.registry().register(
539     ///     &mut socket,
540     ///     Token(0),
541     ///     Interest::READABLE | Interest::WRITABLE)?;
542     ///
543     /// let mut events = Events::with_capacity(1024);
544     /// let start = Instant::now();
545     /// let timeout = Duration::from_millis(500);
546     ///
547     /// loop {
548     ///     let elapsed = start.elapsed();
549     ///
550     ///     if elapsed >= timeout {
551     ///         // Connection timed out
552     ///         return Ok(());
553     ///     }
554     ///
555     ///     let remaining = timeout - elapsed;
556     ///     poll.poll(&mut events, Some(remaining))?;
557     ///
558     ///     for event in &events {
559     ///         if event.token() == Token(0) {
560     ///             // Something (probably) happened on the socket.
561     ///             return Ok(());
562     ///         }
563     ///     }
564     /// }
565     /// # }
566     /// ```
register<S>(&self, source: &mut S, token: Token, interests: Interest) -> io::Result<()> where S: event::Source + ?Sized,567     pub fn register<S>(&self, source: &mut S, token: Token, interests: Interest) -> io::Result<()>
568     where
569         S: event::Source + ?Sized,
570     {
571         trace!(
572             "registering event source with poller: token={:?}, interests={:?}",
573             token,
574             interests
575         );
576         source.register(self, token, interests)
577     }
578 
579     /// Re-register an [`event::Source`] with the `Poll` instance.
580     ///
581     /// Re-registering an event source allows changing the details of the
582     /// registration. Specifically, it allows updating the associated `token`
583     /// and `interests` specified in previous `register` and `reregister` calls.
584     ///
585     /// The `reregister` arguments fully override the previous values. In other
586     /// words, if a socket is registered with [`readable`] interest and the call
587     /// to `reregister` specifies [`writable`], then read interest is no longer
588     /// requested for the handle.
589     ///
590     /// The event source must have previously been registered with this instance
591     /// of `Poll`, otherwise the behavior is unspecified.
592     ///
593     /// See the [`register`] documentation for details about the function
594     /// arguments and see the [`struct`] docs for a high level overview of
595     /// polling.
596     ///
597     /// # Examples
598     ///
599     #[cfg_attr(all(feature = "os-poll", feature = "net"), doc = "```")]
600     #[cfg_attr(not(all(feature = "os-poll", feature = "net")), doc = "```ignore")]
601     /// # use std::error::Error;
602     /// # use std::net;
603     /// # fn main() -> Result<(), Box<dyn Error>> {
604     /// use mio::{Poll, Interest, Token};
605     /// use mio::net::TcpStream;
606     /// use std::net::SocketAddr;
607     ///
608     /// let poll = Poll::new()?;
609     ///
610     /// let address: SocketAddr = "127.0.0.1:0".parse()?;
611     /// let listener = net::TcpListener::bind(address)?;
612     /// let mut socket = TcpStream::connect(listener.local_addr()?)?;
613     ///
614     /// // Register the socket with `poll`, requesting readable
615     /// poll.registry().register(
616     ///     &mut socket,
617     ///     Token(0),
618     ///     Interest::READABLE)?;
619     ///
620     /// // Reregister the socket specifying write interest instead. Even though
621     /// // the token is the same it must be specified.
622     /// poll.registry().reregister(
623     ///     &mut socket,
624     ///     Token(0),
625     ///     Interest::WRITABLE)?;
626     /// #     Ok(())
627     /// # }
628     /// ```
629     ///
630     /// [`event::Source`]: ./event/trait.Source.html
631     /// [`struct`]: struct.Poll.html
632     /// [`register`]: struct.Registry.html#method.register
633     /// [`readable`]: ./event/struct.Event.html#is_readable
634     /// [`writable`]: ./event/struct.Event.html#is_writable
reregister<S>(&self, source: &mut S, token: Token, interests: Interest) -> io::Result<()> where S: event::Source + ?Sized,635     pub fn reregister<S>(&self, source: &mut S, token: Token, interests: Interest) -> io::Result<()>
636     where
637         S: event::Source + ?Sized,
638     {
639         trace!(
640             "reregistering event source with poller: token={:?}, interests={:?}",
641             token,
642             interests
643         );
644         source.reregister(self, token, interests)
645     }
646 
647     /// Deregister an [`event::Source`] with the `Poll` instance.
648     ///
649     /// When an event source is deregistered, the `Poll` instance will no longer
650     /// monitor it for readiness state changes. Deregistering clears up any
651     /// internal resources needed to track the handle.  After an explicit call
652     /// to this method completes, it is guaranteed that the token previously
653     /// registered to this handle will not be returned by a future poll, so long
654     /// as a happens-before relationship is established between this call and
655     /// the poll.
656     ///
657     /// The event source must have previously been registered with this instance
658     /// of `Poll`, otherwise the behavior is unspecified.
659     ///
660     /// A handle can be passed back to `register` after it has been
661     /// deregistered; however, it must be passed back to the **same** `Poll`
662     /// instance, otherwise the behavior is unspecified.
663     ///
664     /// # Examples
665     ///
666     #[cfg_attr(all(feature = "os-poll", feature = "net"), doc = "```")]
667     #[cfg_attr(not(all(feature = "os-poll", feature = "net")), doc = "```ignore")]
668     /// # use std::error::Error;
669     /// # use std::net;
670     /// # fn main() -> Result<(), Box<dyn Error>> {
671     /// use mio::{Events, Poll, Interest, Token};
672     /// use mio::net::TcpStream;
673     /// use std::net::SocketAddr;
674     /// use std::time::Duration;
675     ///
676     /// let mut poll = Poll::new()?;
677     ///
678     /// let address: SocketAddr = "127.0.0.1:0".parse()?;
679     /// let listener = net::TcpListener::bind(address)?;
680     /// let mut socket = TcpStream::connect(listener.local_addr()?)?;
681     ///
682     /// // Register the socket with `poll`
683     /// poll.registry().register(
684     ///     &mut socket,
685     ///     Token(0),
686     ///     Interest::READABLE)?;
687     ///
688     /// poll.registry().deregister(&mut socket)?;
689     ///
690     /// let mut events = Events::with_capacity(1024);
691     ///
692     /// // Set a timeout because this poll should never receive any events.
693     /// poll.poll(&mut events, Some(Duration::from_secs(1)))?;
694     /// assert!(events.is_empty());
695     /// #     Ok(())
696     /// # }
697     /// ```
deregister<S>(&self, source: &mut S) -> io::Result<()> where S: event::Source + ?Sized,698     pub fn deregister<S>(&self, source: &mut S) -> io::Result<()>
699     where
700         S: event::Source + ?Sized,
701     {
702         trace!("deregistering event source from poller");
703         source.deregister(self)
704     }
705 
706     /// Creates a new independently owned `Registry`.
707     ///
708     /// Event sources registered with this `Registry` will be registered with
709     /// the original `Registry` and `Poll` instance.
try_clone(&self) -> io::Result<Registry>710     pub fn try_clone(&self) -> io::Result<Registry> {
711         self.selector.try_clone().map(|selector| Registry {
712             selector,
713             #[cfg(all(debug_assertions, not(target_os = "wasi")))]
714             has_waker: Arc::clone(&self.has_waker),
715         })
716     }
717 
718     /// Internal check to ensure only a single `Waker` is active per [`Poll`]
719     /// instance.
720     #[cfg(all(debug_assertions, not(target_os = "wasi")))]
register_waker(&self)721     pub(crate) fn register_waker(&self) {
722         assert!(
723             !self.has_waker.swap(true, Ordering::AcqRel),
724             "Only a single `Waker` can be active per `Poll` instance"
725         );
726     }
727 
728     /// Get access to the `sys::Selector`.
729     #[cfg(any(not(target_os = "wasi"), feature = "net"))]
selector(&self) -> &sys::Selector730     pub(crate) fn selector(&self) -> &sys::Selector {
731         &self.selector
732     }
733 }
734 
735 impl fmt::Debug for Registry {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result736     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
737         fmt.debug_struct("Registry").finish()
738     }
739 }
740 
741 #[cfg(all(
742     unix,
743     not(mio_unsupported_force_poll_poll),
744     not(any(
745         target_os = "aix",
746         target_os = "espidf",
747         target_os = "haiku",
748         target_os = "fuchsia",
749         target_os = "hermit",
750         target_os = "hurd",
751         target_os = "nto",
752         target_os = "solaris",
753         target_os = "vita"
754     )),
755 ))]
756 impl AsRawFd for Registry {
as_raw_fd(&self) -> RawFd757     fn as_raw_fd(&self) -> RawFd {
758         self.selector.as_raw_fd()
759     }
760 }
761 
762 cfg_os_poll! {
763     #[cfg(all(
764         unix,
765         not(mio_unsupported_force_poll_poll),
766         not(any(
767             target_os = "espidf",
768             target_os = "hermit",
769             target_os = "hurd",
770             target_os = "nto",
771             target_os = "solaris",
772             target_os = "vita"
773         )),
774     ))]
775     #[test]
776     pub fn as_raw_fd() {
777         let poll = Poll::new().unwrap();
778         assert!(poll.as_raw_fd() > 0);
779     }
780 }
781