@@ -502,44 +502,76 @@ fn run_ready(
502502/// The [`select!`] macro is a convenience wrapper around `Select`. However, it cannot select over a
503503/// dynamically created list of channel operations.
504504///
505- /// [`select!`]: macro.select.html
505+ /// Once a list of operations has been built with `Select`, there are two different ways of
506+ /// proceeding:
507+ ///
508+ /// * Select an operation with [`try_select`], [`select`], or [`select_timeout`]. If successful,
509+ /// the returned selected operation has already begun and **must** be completed. If we don't
510+ /// complete it, a panic will occur.
511+ ///
512+ /// * Wait for an operation to become ready with [`try_ready`], [`ready`], or [`ready_timeout`]. If
513+ /// successful, we may attempt to execute the operation, but are not obliged to. In fact, it's
514+ /// possible for another thread to make the operation not ready just before we try executing it,
515+ /// so it's wise to use a retry loop.
506516///
507517/// # Examples
508518///
509- /// Receive a message from a list of channels :
519+ /// Use [`select`] to receive a message from a list of receivers :
510520///
511521/// ```
512- /// use std::thread;
513- /// use std::time::Duration;
514- /// use crossbeam_channel::{unbounded, Receiver, Select, Sender};
522+ /// use crossbeam_channel::{Receiver, RecvError, Select};
515523///
516- /// // Create 10 channels.
517- /// let chans: Vec<(Sender<&str>, Receiver<&str>)> = (0..10)
518- /// .map(|_| unbounded())
519- /// .collect();
524+ /// fn recv_multiple<T>(rs: &[Receiver<T>]) -> Result<T, RecvError> {
525+ /// // Build a list of operations.
526+ /// let mut sel = Select::new();
527+ /// for r in rs {
528+ /// sel.recv(r);
529+ /// }
520530///
521- /// // Spawn a thread that delivers a message to the 5th channel after 1 second.
522- /// let s = chans[5].0.clone();
523- /// thread::spawn(move || {
524- /// thread::sleep(Duration::from_secs(1));
525- /// s.send("hello").unwrap();
526- /// });
527- ///
528- /// // Wait until a message is received from one of the channels.
529- /// let mut sel = Select::new();
530- /// for (_, r) in &chans {
531- /// sel.recv(r);
531+ /// // Complete the selected operation.
532+ /// let oper = sel.select();
533+ /// let index = oper.index();
534+ /// oper.recv(&rs[index])
532535/// }
533- /// let oper = sel.select();
536+ /// ```
534537///
535- /// // Complete the selected operation.
536- /// let index = oper.index();
537- /// let r = &chans[index].1;
538- /// let res = oper.recv(r);
538+ /// Use [`ready`] to receive a message from a list of receivers:
539539///
540- /// assert_eq!(index, 5);
541- /// assert_eq!(res, Ok("hello"));
542540/// ```
541+ /// use crossbeam_channel::{Receiver, RecvError, Select};
542+ ///
543+ /// fn recv_multiple<T>(rs: &[Receiver<T>]) -> Result<T, RecvError> {
544+ /// // Build a list of operations.
545+ /// let mut sel = Select::new();
546+ /// for r in rs {
547+ /// sel.recv(r);
548+ /// }
549+ ///
550+ /// loop {
551+ /// // Wait until a receive operation becomes ready and try executing it.
552+ /// let index = sel.ready();
553+ /// let res = rs[index].try_recv();
554+ ///
555+ /// // If the operation turns out not to be ready, retry.
556+ /// if let Err(e) = res {
557+ /// if e.is_empty() {
558+ /// continue;
559+ /// }
560+ /// }
561+ ///
562+ /// // Success!
563+ /// return res.map_err(|_| RecvError);
564+ /// }
565+ /// }
566+ /// ```
567+ ///
568+ /// [`select!`]: macro.select.html
569+ /// [`try_select`]: struct.Select.html#method.try_select
570+ /// [`select`]: struct.Select.html#method.select
571+ /// [`select_timeout`]: struct.Select.html#method.select_timeout
572+ /// [`try_ready`]: struct.Select.html#method.try_ready
573+ /// [`ready`]: struct.Select.html#method.ready
574+ /// [`ready_timeout`]: struct.Select.html#method.ready_timeout
543575pub struct Select < ' a > {
544576 /// A list of senders and receivers participating in selection.
545577 handles : SmallVec < [ ( & ' a SelectHandle , usize , * const u8 ) ; 4 ] > ,
@@ -577,18 +609,10 @@ impl<'a> Select<'a> {
577609 /// use std::thread;
578610 /// use crossbeam_channel::{unbounded, Select};
579611 ///
580- /// let (s1, r1) = unbounded::<i32>();
581- /// let (s2, r2) = unbounded::<i32>();
582- /// let (s3, r3) = unbounded::<i32>();
612+ /// let (s, r) = unbounded::<i32>();
583613 ///
584614 /// let mut sel = Select::new();
585- /// let oper1 = sel.send(&s1);
586- /// let oper2 = sel.send(&s2);
587- /// let oper3 = sel.send(&s3);
588- ///
589- /// assert_eq!(oper1, 0);
590- /// assert_eq!(oper2, 1);
591- /// assert_eq!(oper3, 2);
615+ /// let index = sel.send(&s);
592616 /// ```
593617 pub fn send < T > ( & mut self , s : & ' a Sender < T > ) -> usize {
594618 let i = self . handles . len ( ) ;
@@ -607,18 +631,10 @@ impl<'a> Select<'a> {
607631 /// use std::thread;
608632 /// use crossbeam_channel::{unbounded, Select};
609633 ///
610- /// let (s1, r1) = unbounded::<i32>();
611- /// let (s2, r2) = unbounded::<i32>();
612- /// let (s3, r3) = unbounded::<i32>();
634+ /// let (s, r) = unbounded::<i32>();
613635 ///
614636 /// let mut sel = Select::new();
615- /// let oper1 = sel.recv(&r1);
616- /// let oper2 = sel.recv(&r2);
617- /// let oper3 = sel.recv(&r3);
618- ///
619- /// assert_eq!(oper1, 0);
620- /// assert_eq!(oper2, 1);
621- /// assert_eq!(oper3, 2);
637+ /// let index = sel.recv(&r);
622638 /// ```
623639 pub fn recv < T > ( & mut self , r : & ' a Receiver < T > ) -> usize {
624640 let i = self . handles . len ( ) ;
0 commit comments