## Poll

# Struct Poll

Source

    pub struct Poll { /* private fields */ }

Expand description

Polls for readiness events on all registered values.

`Poll` allows a program to monitor a large number of `event::Source`s, waiting until one or more become “ready” for some class of operations; e.g. reading and writing. An event source is considered ready if it is possible to immediately perform a corresponding operation; e.g. `read` or `write`.

To use `Poll`, an `event::Source` must first be registered with the `Poll` instance using the `register` method on its associated `Register`, supplying readiness interest. The readiness interest tells `Poll` which specific operations on the handle to monitor for readiness. A `Token` is also passed to the `register` function. When `Poll` returns a readiness event, it will include this token. This associates the event with the event source that generated the event.

## §Examples

A basic example – establishing a `TcpStream` connection.

    use mio::{Events, Poll, Interest, Token};
    use mio::net::TcpStream;

    use std::net::{self, SocketAddr};

    // Bind a server socket to connect to.
    let addr: SocketAddr = "127.0.0.1:0".parse()?;
    let server = net::TcpListener::bind(addr)?;

    // Construct a new `Poll` handle as well as the `Events` we'll store into
    let mut poll = Poll::new()?;
    let mut events = Events::with_capacity(1024);

    // Connect the stream
    let mut stream = TcpStream::connect(server.local_addr()?)?;

    // Register the stream with `Poll`
    poll.registry().register(&mut stream, Token(0), Interest::READABLE | Interest::WRITABLE)?;

    // Wait for the socket to become ready. This has to happens in a loop to
    // handle spurious wakeups.
    loop {
        poll.poll(&mut events, None)?;

        for event in &events {
            if event.token() == Token(0) && event.is_writable() {
                // The socket connected (probably, it could still be a spurious
                // wakeup)
                return Ok(());
            }
        }
    }

## §Portability

Using `Poll` provides a portable interface across supported platforms as long as the caller takes the following into consideration:

#### §Spurious events

`Poll::poll` may return readiness events even if the associated event source is not actually ready. Given the same code, this may happen more on some platforms than others. It is important to never assume that, just because a readiness event was received, that the associated operation will succeed as well.

If operation fails with `WouldBlock`, then the caller should not treat this as an error, but instead should wait until another readiness event is received.

#### §Draining readiness

Once a readiness event is received, the corresponding operation must be performed repeatedly until it returns `WouldBlock`. Unless this is done, there is no guarantee that another readiness event will be delivered, even if further data is received for the event source.

#### §Readiness operations

The only readiness operations that are guaranteed to be present on all supported platforms are `readable` and `writable`. All other readiness operations may have false negatives and as such should be considered hints. This means that if a socket is registered with `readable` interest and either an error or close is received, a readiness event will be generated for the socket, but it may only include `readable` readiness. Also note that, given the potential for spurious events, receiving a readiness event with `read_closed`, `write_closed`, or `error` doesn’t actually mean that a `read` on the socket will return a result matching the readiness event.

In other words, portable programs that explicitly check for `read_closed`, `write_closed`, or `error` readiness should be doing so as an optimization and always be able to handle an error or close situation when performing the actual read operation.

#### §Registering handles

Unless otherwise noted, it should be assumed that types implementing `event::Source` will never become ready unless they are registered with `Poll`.

For example:

    use mio::{Poll, Interest, Token};
    use mio::net::TcpStream;
    use std::net::SocketAddr;
    use std::time::Duration;
    use std::thread;

    let address: SocketAddr = "127.0.0.1:0".parse()?;
    let listener = net::TcpListener::bind(address)?;
    let mut sock = TcpStream::connect(listener.local_addr()?)?;

    thread::sleep(Duration::from_secs(1));

    let poll = Poll::new()?;

    // The connect is not guaranteed to have started until it is registered at
    // this point
    poll.registry().register(&mut sock, Token(0), Interest::READABLE | Interest::WRITABLE)?;

#### §Dropping `Poll`

When the `Poll` instance is dropped it may cancel in-flight operations for the registered event sources, meaning that no further events for them may be received. It also means operations on the registered event sources may no longer work. It is up to the user to keep the `Poll` instance alive while registered event sources are being used.

#### §Accessing raw fd/socket/handle

Mio makes it possible for many types to be converted into a raw file descriptor (fd, Unix), socket (Windows) or handle (Windows). This makes it possible to support more operations on the type than Mio supports, for example it makes mio-aio possible. However accessing the raw fd is not without it’s pitfalls.

Specifically performing I/O operations outside of Mio on these types (via the raw fd) has unspecified behaviour. It could cause no more events to be generated for the type even though it returned `WouldBlock` (in an operation directly accessing the fd). The behaviour is OS specific and Mio can only guarantee cross-platform behaviour if it can control the I/O.

The following is not guaranteed, just a description of the current situation! Mio is allowed to change the following without it being considered a breaking change, don’t depend on this, it’s just here to inform the user. Currently the kqueue and epoll implementation support direct I/O operations on the fd without Mio’s knowledge. Windows however needs all I/O operations to go through Mio otherwise it is not able to update it’s internal state properly and won’t generate events.

#### §Polling without registering event sources

The following is not guaranteed, just a description of the current situation! Mio is allowed to change the following without it being considered a breaking change, don’t depend on this, it’s just here to inform the user. On platforms that use epoll, kqueue or IOCP (see implementation notes below) polling without previously registering event sources will result in sleeping forever, only a process signal will be able to wake up the thread.

On WASM/WASI this is different as it doesn’t support process signals, furthermore the WASI specification doesn’t specify a behaviour in this situation, thus it’s up to the implementation what to do here. As an example, the wasmtime runtime will return `EINVAL` in this situation, but different runtimes may return different results. If you have further insights or thoughts about this situation (and/or how Mio should handle it) please add you comment to pull request#1580.

## §Implementation notes

`Poll` is backed by the selector provided by the operating system.

OS | Selector
--- | ---
Android | epoll
DragonFly BSD | kqueue
FreeBSD | kqueue
iOS | kqueue
illumos | epoll
Linux | epoll
NetBSD | kqueue
OpenBSD | kqueue
Windows | IOCP
macOS | kqueue

On all supported platforms, socket operations are handled by using the system selector. Platform specific extensions (e.g. `SourceFd`) allow accessing other features provided by individual system selectors. For example, Linux’s `signalfd` feature can be used by registering the FD with `Poll` via `SourceFd`.

On all platforms except windows, a call to `Poll::poll` is mostly just a direct call to the system selector. However, IOCP uses a completion model instead of a readiness model. In this case, `Poll` must adapt the completion model Mio’s API. While non-trivial, the bridge layer is still quite efficient. The most expensive part being calls to `read` and `write` require data to be copied into an intermediate buffer before it is passed to the kernel.

## Implementations§

Source§

### impl Poll

Source

#### pub fn new() -> Result<Poll>

Return a new `Poll` handle.

This function will make a syscall to the operating system to create the system selector. If this syscall fails, `Poll::new` will return with the error.

close-on-exec flag is set on the file descriptors used by the selector to prevent leaking it to executed processes. However, on some systems such as old Linux systems that don’t support `epoll_create1` syscall it is done non-atomically, so a separate thread executing in parallel to this function may accidentally leak the file descriptor if it executes a new process before this function returns.

See struct level docs for more details.

##### §Examples

    use mio::{Poll, Events};
    use std::time::Duration;

    let mut poll = match Poll::new() {
        Ok(poll) => poll,
        Err(e) => panic!("failed to create Poll instance; err={:?}", e),
    };

    // Create a structure to receive polled events
    let mut events = Events::with_capacity(1024);

    // Wait for events, but none will be received because no
    // `event::Source`s have been registered with this `Poll` instance.
    poll.poll(&mut events, Some(Duration::from_millis(500)))?;
    assert!(events.is_empty());

Source

#### pub fn registry(&self) -> &Registry

Returns a `Registry` which can be used to register `event::Source`s.

Source

#### pub fn poll( &mut self, events: &mut Events, timeout: Option<Duration>, ) -> Result<()>

Wait for readiness events

Blocks the current thread and waits for readiness events for any of the `event::Source`s that have been registered with this `Poll` instance. The function will block until either at least one readiness event has been received or `timeout` has elapsed. A `timeout` of `None` means that `poll` will block until a readiness event has been received.

The supplied `events` will be cleared and newly received readiness events will be pushed onto the end. At most `events.capacity()` events will be returned. If there are further pending readiness events, they will be returned on the next call to `poll`.

A single call to `poll` may result in multiple readiness events being returned for a single event source. For example, if a TCP socket becomes both readable and writable, it may be possible for a single readiness event to be returned with both `readable` and `writable` readiness OR two separate events may be returned, one with `readable` set and one with `writable` set.

Note that the `timeout` will be rounded up to the system clock granularity (usually 1ms), and kernel scheduling delays mean that the blocking interval may be overrun by a small amount.

See the struct level documentation for a higher level discussion of polling.

##### §Notes

This returns any errors without attempting to retry, previous versions of Mio would automatically retry the poll call if it was interrupted (if `EINTR` was returned).

Currently if the `timeout` elapses without any readiness events triggering this will return `Ok(())`. However we’re not guaranteeing this behaviour as this depends on the OS.

##### §Examples

A basic example – establishing a `TcpStream` connection.

    use mio::{Events, Poll, Interest, Token};
    use mio::net::TcpStream;

    use std::net::{TcpListener, SocketAddr};
    use std::thread;

    // Bind a server socket to connect to.
    let addr: SocketAddr = "127.0.0.1:0".parse()?;
    let server = TcpListener::bind(addr)?;
    let addr = server.local_addr()?.clone();

    // Spawn a thread to accept the socket
    thread::spawn(move || {
        let _ = server.accept();
    });

    // Construct a new `Poll` handle as well as the `Events` we'll store into
    let mut poll = Poll::new()?;
    let mut events = Events::with_capacity(1024);

    // Connect the stream
    let mut stream = TcpStream::connect(addr)?;

    // Register the stream with `Poll`
    poll.registry().register(
        &mut stream,
        Token(0),
        Interest::READABLE | Interest::WRITABLE)?;

    // Wait for the socket to become ready. This has to happens in a loop to
    // handle spurious wakeups.
    loop {
        poll.poll(&mut events, None)?;

        for event in &events {
            if event.token() == Token(0) && event.is_writable() {
                // The socket connected (probably, it could still be a spurious
                // wakeup)
                return Ok(());
            }
        }
    }

## Trait Implementations§

Source§

### impl AsRawFd for Poll

Source§

#### fn as_raw_fd(&self) -> RawFd

Extracts the raw file descriptor. Read more
Source§

### impl Debug for Poll

Source§

#### fn fmt(&self, fmt: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

## Auto Trait Implementations§

§

### impl Freeze for Poll

§

### impl RefUnwindSafe for Poll

§

### impl Send for Poll

§

### impl Sync for Poll

§

### impl Unpin for Poll

§

### impl UnwindSafe for Poll

## Blanket Implementations§

Source§

### impl<T> Any for T
where T: 'static + ?Sized,

Source§

#### fn type_id(&self) -> TypeId

Gets the `TypeId` of `self`. Read more
Source§

### impl<T> Borrow<T> for T
where T: ?Sized,

Source§

#### fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

### impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

#### fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

### impl<T> From<T> for T

Source§

#### fn from(t: T) -> T

Returns the argument unchanged.

Source§

### impl<T, U> Into<U> for T
where U: From<T>,

Source§

#### fn into(self) -> U

Calls `U::from(self)`.

That is, this conversion is whatever the implementation of `From<T> for U` chooses to do.

Source§

### impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

#### type Error = Infallible

The type returned in the event of a conversion error.
Source§

#### fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

### impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

#### type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

#### fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.