[][src]Function gaea::poll

pub fn poll<ES, E>(
    event_sources: &mut [&mut dyn Source<ES, E>],
    event_sink: &mut ES,
    timeout: Option<Duration>
) -> Result<(), E> where
    ES: Sink

Poll event sources for readiness events.

This first determines the maximum timeout to use based on the provided timeout and the provided event_sources. For example if one of the sources is Timers with a deadline of 1 second and a supplied timeout of 10 seconds we don't want to block for the whole 10 seconds and overrun the deadline by 9 seconds. Instead we'll use 1 seconds as timeout.

Next it will use the computed timeout in a blocking poll call of the first of the provided event_sources for readiness events. This call will block the current thread until a readiness event is ready or the timeout has elapsed. After the blocking poll the other event sources will be polled for readiness events, without blocking the thread further.

Readiness events will be added to the supplied event_sink. If not all events fit into the event sink, they will be returned in the next call to poll.

Providing a timeout of None means that poll will block until the blocking_source is awoken by an external factor, what this means is different for each event source.

Handling different error types

Each event::Source might have a different concrete error type, for example OsQueue has a concrete error type of io::Error. However we would still like to have a single error type returned from a call to poll. To facilitate this each event source will convert there concrete error into a user defined error (the generic parameter E), this way different error types can be collected into a single type. In most cases this will be io::Error, but this can also be custom enum type as see the second example below.

Note that some event source don't return an error, for example both Queue and Timers don't return an error as they are both implemented in user space and will accept any type as error type (as they don't use it).

Examples

Polling from an OsQueue, Queue and Timers.

use std::io;
use std::time::Instant;

use gaea::{event, OsQueue, Timers, Queue, Event, Ready, poll};

// Our event sources.
let mut os_queue = OsQueue::new()?;
let mut timers = Timers::new();
let mut queue = Queue::new();

// Our event sink.
let mut event_sink = Vec::new();

// Add an event to one of our event sources.
timers.add_deadline(event::Id(0), Instant::now());

// Poll all event sources without a timeout.
poll::<_, io::Error>(&mut [&mut os_queue, &mut timers, &mut queue], &mut event_sink, None)?;
// Even though we didn't provide a timeout `poll` will return without
// blocking because an event is ready.
assert_eq!(event_sink[0], Event::new(event::Id(0), Ready::TIMER));

Using a custom enum error that collects errors from the different event sources.

use gaea::poll;

/// Our custom `event::Source`s.
// Note: implementations not shown for brevity. See `event::Source` for an
// example implementation.
struct EventSource1;
struct EventSource2;

/// `event::Source` error types.
struct SourceError1;
struct SourceError2;

/// Our custom error type.
#[derive(Debug)]
enum MyError {
    Source1,
    Source2,
}

// Implementing `From` allows the error to be converted into our custom
// error type.
// Note: this is also implemented for `SourceError2`, but not show for
// brevity.
impl From<SourceError1> for MyError {
    fn from(_err: SourceError1) -> MyError {
        MyError::Source1
    }
}

// Our event sources.
let mut event_source1 = EventSource1; // With error type `SourceError1`.
let mut event_source2 = EventSource2; // With error type `SourceError2`.
// And event sink.
let mut event_sink = Vec::new();

// Poll both event sources converting any errors into our `MyError` type.
poll::<_, MyError>(&mut [&mut event_source1, &mut event_source2], &mut event_sink, None)?;

// Handle events, etc.