[−][src]Struct mio_st::poll::Poller
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]
&mut self,
handle: &mut E,
id: EventedId,
interests: Interests,
opt: PollOption
) -> Result<()> where
E: Evented,
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]
&mut self,
handle: &mut E,
id: EventedId,
interests: Interests,
opt: PollOption
) -> Result<()> where
E: Evented,
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]
E: Evented,
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]
&mut self,
events: &mut Events,
timeout: Option<Duration>
) -> Result<()>
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
Auto Trait Implementations
Blanket Implementations
impl<T> From for T
[src]
impl<T, U> Into for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = !
try_from
)The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T> Borrow for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> BorrowMut for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T, U> TryInto for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,