Struct crossbeam_channel::Select[][src]

#[must_use]
pub struct Select<'a, R> { /* fields omitted */ }

Waits on a set of channel operations.

This struct with builder-like interface allows declaring a set of channel operations and blocking until any one of them becomes ready. Finally, one of the operations is executed. If multiple operations are ready at the same time, a random one is chosen. It is also possible to declare a default case that gets executed if none of the operations are initially ready.

Note that this method of selecting over channel operations is typically somewhat slower than the select! macro.

Receiving

Receiving a message from two channels, whichever becomes ready first:

use std::thread;
use crossbeam_channel as channel;

let (s1, r1) = channel::unbounded();
let (s2, r2) = channel::unbounded();

thread::spawn(move || s1.send("foo"));
thread::spawn(move || s2.send("bar"));

// Only one of these two receive operations will be executed.
channel::Select::new()
    .recv(&r1, |msg| assert_eq!(msg, Some("foo")))
    .recv(&r2, |msg| assert_eq!(msg, Some("bar")))
    .wait();

Sending

Waiting on a send and a receive operation:

use std::thread;
use crossbeam_channel as channel;

let (s1, r1) = channel::unbounded();
let (s2, r2) = channel::unbounded();

s1.send("foo");

// Since both operations are initially ready, a random one will be executed.
channel::Select::new()
    .recv(&r1, |msg| assert_eq!(msg, Some("foo")))
    .send(&s2, || "bar", || assert_eq!(r2.recv(), Some("bar")))
    .wait();

Default case

A special kind of case is default, which gets executed if none of the operations can be executed, i.e. they would block:

use std::thread;
use std::time::{Duration, Instant};
use crossbeam_channel as channel;

let (s, r) = channel::unbounded();

thread::spawn(move || {
    thread::sleep(Duration::from_secs(1));
    s.send("foo");
});

// Don't block on the receive operation.
channel::Select::new()
    .recv(&r, |_| panic!())
    .default(|| println!("The message is not yet available."))
    .wait();

Execution

  1. A Select is constructed, cases are added, and .wait() is called.
  2. If any of the recv or send operations are ready, one of them is executed. If multiple operations are ready, a random one is chosen.
  3. If none of the recv and send operations are ready, the default case is executed. If there is no default case, the current thread is blocked until an operation becomes ready.
  4. If a recv operation gets executed, its callback is invoked.
  5. If a send operation gets executed, the message is lazily evaluated and sent into the channel. Finally, the callback is invoked.

Note: If evaluation of the message panics, the process will be aborted because it's impossible to recover from such panics. All the other callbacks are allowed to panic, however.

Methods

impl<'a, R> Select<'a, R>
[src]

Creates a new Select.

Adds a receive case.

The callback will get invoked if the receive operation completes.

Adds a send case.

If the send operation succeeds, the message will be generated and sent into the channel. Finally, the callback gets invoked once the operation is completed.

Note: If function msg panics, the process will be aborted because it's impossible to recover from such panics. However, function cb is allowed to panic.

Adds a default case.

This case gets executed if none of the channel operations are ready.

If called more than once, this method keeps only the last callback for the default case.

Starts selection and waits until it completes.

The result of the executed callback function will be returned.

Auto Trait Implementations

impl<'a, R> !Send for Select<'a, R>

impl<'a, R> !Sync for Select<'a, R>