@@ -502,44 +502,76 @@ fn run_ready(
502
502
/// The [`select!`] macro is a convenience wrapper around `Select`. However, it cannot select over a
503
503
/// dynamically created list of channel operations.
504
504
///
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.
506
516
///
507
517
/// # Examples
508
518
///
509
- /// Receive a message from a list of channels :
519
+ /// Use [`select`] to receive a message from a list of receivers :
510
520
///
511
521
/// ```
512
- /// use std::thread;
513
- /// use std::time::Duration;
514
- /// use crossbeam_channel::{unbounded, Receiver, Select, Sender};
522
+ /// use crossbeam_channel::{Receiver, RecvError, Select};
515
523
///
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
+ /// }
520
530
///
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])
532
535
/// }
533
- /// let oper = sel.select();
536
+ /// ```
534
537
///
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:
539
539
///
540
- /// assert_eq!(index, 5);
541
- /// assert_eq!(res, Ok("hello"));
542
540
/// ```
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
543
575
pub struct Select < ' a > {
544
576
/// A list of senders and receivers participating in selection.
545
577
handles : SmallVec < [ ( & ' a SelectHandle , usize , * const u8 ) ; 4 ] > ,
@@ -577,18 +609,10 @@ impl<'a> Select<'a> {
577
609
/// use std::thread;
578
610
/// use crossbeam_channel::{unbounded, Select};
579
611
///
580
- /// let (s1, r1) = unbounded::<i32>();
581
- /// let (s2, r2) = unbounded::<i32>();
582
- /// let (s3, r3) = unbounded::<i32>();
612
+ /// let (s, r) = unbounded::<i32>();
583
613
///
584
614
/// 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);
592
616
/// ```
593
617
pub fn send < T > ( & mut self , s : & ' a Sender < T > ) -> usize {
594
618
let i = self . handles . len ( ) ;
@@ -607,18 +631,10 @@ impl<'a> Select<'a> {
607
631
/// use std::thread;
608
632
/// use crossbeam_channel::{unbounded, Select};
609
633
///
610
- /// let (s1, r1) = unbounded::<i32>();
611
- /// let (s2, r2) = unbounded::<i32>();
612
- /// let (s3, r3) = unbounded::<i32>();
634
+ /// let (s, r) = unbounded::<i32>();
613
635
///
614
636
/// 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);
622
638
/// ```
623
639
pub fn recv < T > ( & mut self , r : & ' a Receiver < T > ) -> usize {
624
640
let i = self . handles . len ( ) ;
0 commit comments