[][src]Struct mio_st::poll::Poller

pub struct Poller { /* fields omitted */ }

Polls for readiness events on all registered handles.

Poller allows a program to monitor a large number of Evented handles, waiting until one or more become "ready" for some class of operations; e.g. reading or writing. An Evented type is considered ready if it is possible to immediately perform a corresponding operation; e.g. read or write.

To use Poller an Evented handle must first be registered with the Poller instance using the register method, supplying an associated id, readiness interests and polling option. The associated id, or EventedId, is used to associate an readiness event with an Evented handle. The readiness interests, or Interests, tells Poller which specific operations on the handle to monitor for readiness. And the final argument, PollOption, tells Poller how to deliver the readiness events, see PollOption for more information.

Portability

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

Spurious events

Poller.poll may return readiness events even if the associated Evented handle 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 notification was received, that the associated operation will as well.

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

Draining readiness

When using edge-triggered mode, 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 Evented handle. See PollOption for more.

Registering handles

Unless otherwise noted, it should be assumed that types implementing Evented will never become ready unless they are registered with Poller.

For example:

use std::thread;
use std::time::Duration;

use mio_st::event::EventedId;
use mio_st::net::TcpStream;
use mio_st::poll::{Poller, PollOption};

let address = "216.58.193.100:80".parse()?;
let mut stream = TcpStream::connect(address)?;

// This actually does nothing.
thread::sleep(Duration::from_secs(1));

let mut poller = Poller::new()?;

// The connect is not guaranteed to have started until it is registered at
// this point.
poller.register(&mut stream, EventedId(0), TcpStream::INTERESTS, PollOption::Edge)?;

Implementation notes

Poller is backed by the selector provided by the operating system.

OS Selector
FreeBSD kqueue
Linux epoll
Mac OS kqueue
NetBSD kqueue
OpenBSD kqueue

On all supported platforms socket operations are handled by using the system selector. Platform specific extensions (e.g. EventedFd) allow accessing other features provided by individual system selectors. For example Linux's signalfd feature can be used by registering the file descriptor with Poller via EventedFd.

On all platforms a call to Poller.poll is mostly just a direct call to the system selector, but it also adds user space and timer events. Notifications generated by user space registration are handled by an internal readiness queue. Deadlines and timers use a similar internal queue. A single call to Poller.poll will collect events from all three queues; the system selector, the user space readiness queue and the deadline queue.

Events itself is split among system events and user space events, which includes deadlines and timers.

Methods

impl Poller[src]

pub fn new() -> Result<Poller>[src]

Return a new Poller handle.

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

See struct level docs for more details.

Examples

use std::time::Duration;

use mio_st::event::Events;
use mio_st::poll::Poller;

let mut poller = Poller::new()?;

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

// Wait for events, but none will be received because no `Evented`
// handles have been registered with this `Poller` instance.
poller.poll(&mut events, Some(Duration::from_millis(500)))?;

pub fn register<E: ?Sized>(
    &mut self,
    handle: &mut E,
    id: EventedId,
    interests: Interests,
    opt: PollOption
) -> Result<()> where
    E: Evented
[src]

Register an Evented handle with the Poller instance.

Once registered, the Poller instance will monitor the Evented handle for readiness state changes. When it notices a state change, it will return a readiness event for the handle the next time poll is called.

See the struct docs for a high level overview.

Arguments

handle: This is the handle that the Poller instance should monitor for readiness state changes.

id: The caller picks a id to associate with the handle. When poll returns an event for the handle, this id is included. This allows the caller to map the event to its handle. The id associated with the Evented handle can be changed at any time by calling reregister.

interests: Specifies which operations Poller should monitor for readiness. Poller will only return readiness events for operations specified by this argument. If a socket is registered with readable interests and the socket becomes writable, no event will be returned from poll. The readiness interests for an Evented handle can be changed at any time by calling reregister. Most types have a associated constant named INTERESTS which provide a good default value.

opt: Specifies the registration option. Just like the interests, the option can be changed for an Evented handle at any time by calling reregister.

Notes

Unless otherwise specified, the caller should assume that once an Evented handle is registered with a Poller instance, it is bound to that Poller instance for the lifetime of the Evented handle. This remains true even if the Evented handle is deregistered from the poll instance using deregister.

Examples

use mio_st::event::{Events, EventedId};
use mio_st::net::TcpStream;
use mio_st::poll::{Poller, PollOption};

// Create a new `Poller` instance as well a containers for the vents.
let mut poller = Poller::new()?;
let mut events = Events::new();

// Create a TCP connection. `TcpStream` implements the `Evented` trait.
let address = "216.58.193.100:80".parse()?;
let mut stream = TcpStream::connect(address)?;

// Register the connection with `poller`.
poller.register(&mut stream, EventedId(0), TcpStream::INTERESTS, PollOption::Edge)?;

// Start the event loop.
loop {
    poller.poll(&mut events, None)?;

    for event in &mut events {
        if event.id() == EventedId(0) {
            // Connection is (likely) ready for use.
        }
    }
}

pub fn reregister<E: ?Sized>(
    &mut self,
    handle: &mut E,
    id: EventedId,
    interests: Interests,
    opt: PollOption
) -> Result<()> where
    E: Evented
[src]

Re-register an Evented handle with the Poller instance.

Re-registering an Evented handle allows changing the details of the registration. Specifically, it allows updating the associated id, interests, and opt specified in previous register and reregister calls.

The reregister arguments fully override the previous values. In other words, if a socket is registered with readable interest and the call to reregister specifies only writable, then read interest is no longer requested for the handle.

The Evented handle must have previously been registered with this instance of Poller otherwise the call to reregister may return an error.

See the register documentation for details about the function arguments and see the struct docs for a high level overview of polling.

Examples

use mio_st::event::EventedId;
use mio_st::net::TcpStream;
use mio_st::poll::{Interests, PollOption, Poller};

let mut poller = Poller::new()?;

// Create a TCP connection. `TcpStream` implements the `Evented` trait.
let address = "216.58.193.100:80".parse()?;
let mut stream = TcpStream::connect(address)?;

// Register the connection with `Poller`, only with readable interest.
poller.register(&mut stream, EventedId(0), Interests::READABLE, PollOption::Edge)?;

// Reregister the connection specifying a different id and write interest
// instead. `PollOption::Edge` must be specified even though that value
// is not being changed.
poller.reregister(&mut stream, EventedId(2), Interests::WRITABLE, PollOption::Edge)?;

pub fn deregister<E: ?Sized>(&mut self, handle: &mut E) -> Result<()> where
    E: Evented
[src]

Deregister an Evented handle with the Poller instance.

When an Evented handle is deregistered, the Poller instance will no longer monitor it for readiness state changes. Unlike disabling handles with oneshot, deregistering clears up any internal resources needed to track the handle.

A handle can be registered again using register after it has been deregistered; however, it must be passed back to the same Poller instance.

Notes

Calling reregister after deregister may be work on some platforms but not all. To properly re-register a handle after deregistering use register, this works on all platforms.

Examples

use std::time::Duration;

use mio_st::event::{Events, EventedId};
use mio_st::net::TcpStream;
use mio_st::poll::{Poller, PollOption};

let mut poller = Poller::new()?;
let mut events = Events::new();

// Create a TCP connection. `TcpStream` implements the `Evented` trait.
let address = "216.58.193.100:80".parse()?;
let mut stream = TcpStream::connect(address)?;

// Register the connection with `Poller`.
poller.register(&mut stream, EventedId(0), TcpStream::INTERESTS, PollOption::Edge)?;

// Do stuff with the connection etc.

// Deregister it so the resources can be cleaned up.
poller.deregister(&mut stream)?;

// Set a timeout because this poller shouldn't receive any events anymore.
poller.poll(&mut events, Some(Duration::from_millis(200)))?;
assert!(events.is_empty());

pub fn notify(&mut self, id: EventedId, ready: Ready)[src]

Notify an evented handle of an user space event.

This uses the user space event system.

Examples

use mio_st::event::{Event, Events, EventedId, Ready};
use mio_st::poll::Poller;

let mut poller = Poller::new()?;
let mut events = Events::new();

// Add a custom user space notification.
poller.notify(EventedId(0), Ready::READABLE);

poller.poll(&mut events, None)?;
assert_eq!((&mut events).next().unwrap(), Event::new(EventedId(0), Ready::READABLE));

pub fn add_deadline(&mut self, id: EventedId, deadline: Instant)[src]

Add a new deadline to Poller.

This will cause an event to trigger after the deadline has passed with the Ready::TIMER readiness and provided id.

Examples

use std::time::{Duration, Instant};

use mio_st::event::{Event, Events, EventedId, Ready};
use mio_st::poll::Poller;

// Our `Poller` instance and events.
let mut poller = Poller::new()?;
let mut events = Events::new();

// Add our deadline, to trigger an event 10 milliseconds from now.
let deadline = Instant::now() + Duration::from_millis(10);
let id = EventedId(0);
poller.add_deadline(id, deadline);

// Even though we don't provide a timeout to poll this will return in
// roughly 10 milliseconds and return an event with our deadline.
poller.poll(&mut events, None)?;

assert_eq!((&mut events).next(), Some(Event::new(id, Ready::TIMER)));

pub fn remove_deadline(&mut self, id: EventedId)[src]

Remove a previously added deadline.

Notes

Removing a deadline is a costly operation. For better performance it is advised to not bother with removing and instead ignore the event when it comes up.

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

Poll for readiness events.

Blocks the current thread and waits for readiness events for any of the Evented handles that have been registered with this Poller instance previously.

The function will block until either;

  • at least one readiness event has been received from,
  • a deadline is elapsed, or
  • the provided timeout has elapsed.

Providing a timeout of None means that poll will block until one of the other two conditions are true. 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.

The supplied events will be cleared and newly received readiness events will be stored in it. If not all events fit into the 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 Evented handle. 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.

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

pub fn poll_userspace(&mut self, events: &mut Events)[src]

Poll for user space readiness events.

The regular call to poll uses a system call to read readiness events for system resources such as sockets. This method does not do that, it will only read user space readiness events, including deadlines.

Because no system call is used this method is faster then calling poll, even with a 0 ms timeout, and never blocks.

Trait Implementations

impl Debug for Poller[src]

Auto Trait Implementations

impl Send for Poller

impl Sync for Poller

Blanket Implementations

impl<T> From for T[src]

impl<T, U> Into for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T> Borrow for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> BorrowMut for T where
    T: ?Sized
[src]

impl<T, U> TryInto for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.