1305 lines
38 KiB
Rust
1305 lines
38 KiB
Rust
// //! Tests for channel selection using the `Select` struct.
|
|
|
|
// extern crate crossbeam_channel;
|
|
// extern crate crossbeam_utils;
|
|
|
|
// use std::any::Any;
|
|
// use std::cell::Cell;
|
|
// use std::thread;
|
|
// use std::time::{Duration, Instant};
|
|
|
|
// use crossbeam_channel::{after, bounded, tick, unbounded, Receiver, Select, TryRecvError};
|
|
// use crossbeam_utils::thread::scope;
|
|
|
|
// fn ms(ms: u64) -> Duration {
|
|
// Duration::from_millis(ms)
|
|
// }
|
|
|
|
// #[test]
|
|
// fn smoke1() {
|
|
// let (s1, r1) = unbounded::<usize>();
|
|
// let (s2, r2) = unbounded::<usize>();
|
|
|
|
// s1.send(1).unwrap();
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.recv(&r2);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// i if i == oper1 => assert_eq!(oper.recv(&r1), Ok(1)),
|
|
// i if i == oper2 => panic!(),
|
|
// _ => unreachable!(),
|
|
// }
|
|
|
|
// s2.send(2).unwrap();
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.recv(&r2);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// i if i == oper1 => panic!(),
|
|
// i if i == oper2 => assert_eq!(oper.recv(&r2), Ok(2)),
|
|
// _ => unreachable!(),
|
|
// }
|
|
// }
|
|
|
|
// #[test]
|
|
// fn smoke2() {
|
|
// let (_s1, r1) = unbounded::<i32>();
|
|
// let (_s2, r2) = unbounded::<i32>();
|
|
// let (_s3, r3) = unbounded::<i32>();
|
|
// let (_s4, r4) = unbounded::<i32>();
|
|
// let (s5, r5) = unbounded::<i32>();
|
|
|
|
// s5.send(5).unwrap();
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.recv(&r2);
|
|
// let oper3 = sel.recv(&r3);
|
|
// let oper4 = sel.recv(&r4);
|
|
// let oper5 = sel.recv(&r5);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// i if i == oper1 => panic!(),
|
|
// i if i == oper2 => panic!(),
|
|
// i if i == oper3 => panic!(),
|
|
// i if i == oper4 => panic!(),
|
|
// i if i == oper5 => assert_eq!(oper.recv(&r5), Ok(5)),
|
|
// _ => unreachable!(),
|
|
// }
|
|
// }
|
|
|
|
// #[test]
|
|
// fn disconnected() {
|
|
// let (s1, r1) = unbounded::<i32>();
|
|
// let (s2, r2) = unbounded::<i32>();
|
|
|
|
// scope(|scope| {
|
|
// scope.spawn(|_| {
|
|
// drop(s1);
|
|
// thread::sleep(ms(500));
|
|
// s2.send(5).unwrap();
|
|
// });
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.recv(&r2);
|
|
// let oper = sel.select_timeout(ms(1000));
|
|
// match oper {
|
|
// Err(_) => panic!(),
|
|
// Ok(oper) => match oper.index() {
|
|
// i if i == oper1 => assert!(oper.recv(&r1).is_err()),
|
|
// i if i == oper2 => panic!(),
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
|
|
// r2.recv().unwrap();
|
|
// })
|
|
// .unwrap();
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.recv(&r2);
|
|
// let oper = sel.select_timeout(ms(1000));
|
|
// match oper {
|
|
// Err(_) => panic!(),
|
|
// Ok(oper) => match oper.index() {
|
|
// i if i == oper1 => assert!(oper.recv(&r1).is_err()),
|
|
// i if i == oper2 => panic!(),
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
|
|
// scope(|scope| {
|
|
// scope.spawn(|_| {
|
|
// thread::sleep(ms(500));
|
|
// drop(s2);
|
|
// });
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r2);
|
|
// let oper = sel.select_timeout(ms(1000));
|
|
// match oper {
|
|
// Err(_) => panic!(),
|
|
// Ok(oper) => match oper.index() {
|
|
// i if i == oper1 => assert!(oper.recv(&r2).is_err()),
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
// })
|
|
// .unwrap();
|
|
// }
|
|
|
|
// #[test]
|
|
// fn default() {
|
|
// let (s1, r1) = unbounded::<i32>();
|
|
// let (s2, r2) = unbounded::<i32>();
|
|
|
|
// let mut sel = Select::new();
|
|
// let _oper1 = sel.recv(&r1);
|
|
// let _oper2 = sel.recv(&r2);
|
|
// let oper = sel.try_select();
|
|
// match oper {
|
|
// Err(_) => {}
|
|
// Ok(_) => panic!(),
|
|
// }
|
|
|
|
// drop(s1);
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.recv(&r2);
|
|
// let oper = sel.try_select();
|
|
// match oper {
|
|
// Err(_) => panic!(),
|
|
// Ok(oper) => match oper.index() {
|
|
// i if i == oper1 => assert!(oper.recv(&r1).is_err()),
|
|
// i if i == oper2 => panic!(),
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
|
|
// s2.send(2).unwrap();
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r2);
|
|
// let oper = sel.try_select();
|
|
// match oper {
|
|
// Err(_) => panic!(),
|
|
// Ok(oper) => match oper.index() {
|
|
// i if i == oper1 => assert_eq!(oper.recv(&r2), Ok(2)),
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
|
|
// let mut sel = Select::new();
|
|
// let _oper1 = sel.recv(&r2);
|
|
// let oper = sel.try_select();
|
|
// match oper {
|
|
// Err(_) => {}
|
|
// Ok(_) => panic!(),
|
|
// }
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper = sel.try_select();
|
|
// match oper {
|
|
// Err(_) => {}
|
|
// Ok(_) => panic!(),
|
|
// }
|
|
// }
|
|
|
|
// #[test]
|
|
// fn timeout() {
|
|
// let (_s1, r1) = unbounded::<i32>();
|
|
// let (s2, r2) = unbounded::<i32>();
|
|
|
|
// scope(|scope| {
|
|
// scope.spawn(|_| {
|
|
// thread::sleep(ms(1500));
|
|
// s2.send(2).unwrap();
|
|
// });
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.recv(&r2);
|
|
// let oper = sel.select_timeout(ms(1000));
|
|
// match oper {
|
|
// Err(_) => {}
|
|
// Ok(oper) => match oper.index() {
|
|
// i if i == oper1 => panic!(),
|
|
// i if i == oper2 => panic!(),
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.recv(&r2);
|
|
// let oper = sel.select_timeout(ms(1000));
|
|
// match oper {
|
|
// Err(_) => panic!(),
|
|
// Ok(oper) => match oper.index() {
|
|
// i if i == oper1 => panic!(),
|
|
// i if i == oper2 => assert_eq!(oper.recv(&r2), Ok(2)),
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
// })
|
|
// .unwrap();
|
|
|
|
// scope(|scope| {
|
|
// let (s, r) = unbounded::<i32>();
|
|
|
|
// scope.spawn(move |_| {
|
|
// thread::sleep(ms(500));
|
|
// drop(s);
|
|
// });
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper = sel.select_timeout(ms(1000));
|
|
// match oper {
|
|
// Err(_) => {
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r);
|
|
// let oper = sel.try_select();
|
|
// match oper {
|
|
// Err(_) => panic!(),
|
|
// Ok(oper) => match oper.index() {
|
|
// i if i == oper1 => assert!(oper.recv(&r).is_err()),
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
// }
|
|
// Ok(_) => unreachable!(),
|
|
// }
|
|
// })
|
|
// .unwrap();
|
|
// }
|
|
|
|
// #[test]
|
|
// fn default_when_disconnected() {
|
|
// let (_, r) = unbounded::<i32>();
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r);
|
|
// let oper = sel.try_select();
|
|
// match oper {
|
|
// Err(_) => panic!(),
|
|
// Ok(oper) => match oper.index() {
|
|
// i if i == oper1 => assert!(oper.recv(&r).is_err()),
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
|
|
// let (_, r) = unbounded::<i32>();
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r);
|
|
// let oper = sel.select_timeout(ms(1000));
|
|
// match oper {
|
|
// Err(_) => panic!(),
|
|
// Ok(oper) => match oper.index() {
|
|
// i if i == oper1 => assert!(oper.recv(&r).is_err()),
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
|
|
// let (s, _) = bounded::<i32>(0);
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.send(&s);
|
|
// let oper = sel.try_select();
|
|
// match oper {
|
|
// Err(_) => panic!(),
|
|
// Ok(oper) => match oper.index() {
|
|
// i if i == oper1 => assert!(oper.send(&s, 0).is_err()),
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
|
|
// let (s, _) = bounded::<i32>(0);
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.send(&s);
|
|
// let oper = sel.select_timeout(ms(1000));
|
|
// match oper {
|
|
// Err(_) => panic!(),
|
|
// Ok(oper) => match oper.index() {
|
|
// i if i == oper1 => assert!(oper.send(&s, 0).is_err()),
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
// }
|
|
|
|
// #[test]
|
|
// fn default_only() {
|
|
// let start = Instant::now();
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper = sel.try_select();
|
|
// assert!(oper.is_err());
|
|
// let now = Instant::now();
|
|
// assert!(now - start <= ms(50));
|
|
|
|
// let start = Instant::now();
|
|
// let mut sel = Select::new();
|
|
// let oper = sel.select_timeout(ms(500));
|
|
// assert!(oper.is_err());
|
|
// let now = Instant::now();
|
|
// assert!(now - start >= ms(450));
|
|
// assert!(now - start <= ms(550));
|
|
// }
|
|
|
|
// #[test]
|
|
// fn unblocks() {
|
|
// let (s1, r1) = bounded::<i32>(0);
|
|
// let (s2, r2) = bounded::<i32>(0);
|
|
|
|
// scope(|scope| {
|
|
// scope.spawn(|_| {
|
|
// thread::sleep(ms(500));
|
|
// s2.send(2).unwrap();
|
|
// });
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.recv(&r2);
|
|
// let oper = sel.select_timeout(ms(1000));
|
|
// match oper {
|
|
// Err(_) => panic!(),
|
|
// Ok(oper) => match oper.index() {
|
|
// i if i == oper1 => panic!(),
|
|
// i if i == oper2 => assert_eq!(oper.recv(&r2), Ok(2)),
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
// })
|
|
// .unwrap();
|
|
|
|
// scope(|scope| {
|
|
// scope.spawn(|_| {
|
|
// thread::sleep(ms(500));
|
|
// assert_eq!(r1.recv().unwrap(), 1);
|
|
// });
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.send(&s1);
|
|
// let oper2 = sel.send(&s2);
|
|
// let oper = sel.select_timeout(ms(1000));
|
|
// match oper {
|
|
// Err(_) => panic!(),
|
|
// Ok(oper) => match oper.index() {
|
|
// i if i == oper1 => oper.send(&s1, 1).unwrap(),
|
|
// i if i == oper2 => panic!(),
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
// })
|
|
// .unwrap();
|
|
// }
|
|
|
|
// #[test]
|
|
// fn both_ready() {
|
|
// let (s1, r1) = bounded(0);
|
|
// let (s2, r2) = bounded(0);
|
|
|
|
// scope(|scope| {
|
|
// scope.spawn(|_| {
|
|
// thread::sleep(ms(500));
|
|
// s1.send(1).unwrap();
|
|
// assert_eq!(r2.recv().unwrap(), 2);
|
|
// });
|
|
|
|
// for _ in 0..2 {
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.send(&s2);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// i if i == oper1 => assert_eq!(oper.recv(&r1), Ok(1)),
|
|
// i if i == oper2 => oper.send(&s2, 2).unwrap(),
|
|
// _ => unreachable!(),
|
|
// }
|
|
// }
|
|
// })
|
|
// .unwrap();
|
|
// }
|
|
|
|
// #[test]
|
|
// fn loop_try() {
|
|
// const RUNS: usize = 20;
|
|
|
|
// for _ in 0..RUNS {
|
|
// let (s1, r1) = bounded::<i32>(0);
|
|
// let (s2, r2) = bounded::<i32>(0);
|
|
// let (s_end, r_end) = bounded::<()>(0);
|
|
|
|
// scope(|scope| {
|
|
// scope.spawn(|_| loop {
|
|
// let mut done = false;
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.send(&s1);
|
|
// let oper = sel.try_select();
|
|
// match oper {
|
|
// Err(_) => {}
|
|
// Ok(oper) => match oper.index() {
|
|
// i if i == oper1 => {
|
|
// let _ = oper.send(&s1, 1);
|
|
// done = true;
|
|
// }
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
// if done {
|
|
// break;
|
|
// }
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r_end);
|
|
// let oper = sel.try_select();
|
|
// match oper {
|
|
// Err(_) => {}
|
|
// Ok(oper) => match oper.index() {
|
|
// i if i == oper1 => {
|
|
// let _ = oper.recv(&r_end);
|
|
// done = true;
|
|
// }
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
// if done {
|
|
// break;
|
|
// }
|
|
// });
|
|
|
|
// scope.spawn(|_| loop {
|
|
// if let Ok(x) = r2.try_recv() {
|
|
// assert_eq!(x, 2);
|
|
// break;
|
|
// }
|
|
|
|
// let mut done = false;
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r_end);
|
|
// let oper = sel.try_select();
|
|
// match oper {
|
|
// Err(_) => {}
|
|
// Ok(oper) => match oper.index() {
|
|
// i if i == oper1 => {
|
|
// let _ = oper.recv(&r_end);
|
|
// done = true;
|
|
// }
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
// if done {
|
|
// break;
|
|
// }
|
|
// });
|
|
|
|
// scope.spawn(|_| {
|
|
// thread::sleep(ms(500));
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.send(&s2);
|
|
// let oper = sel.select_timeout(ms(1000));
|
|
// match oper {
|
|
// Err(_) => {}
|
|
// Ok(oper) => match oper.index() {
|
|
// i if i == oper1 => assert_eq!(oper.recv(&r1), Ok(1)),
|
|
// i if i == oper2 => assert!(oper.send(&s2, 2).is_ok()),
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
|
|
// drop(s_end);
|
|
// });
|
|
// })
|
|
// .unwrap();
|
|
// }
|
|
// }
|
|
|
|
// #[test]
|
|
// fn cloning1() {
|
|
// scope(|scope| {
|
|
// let (s1, r1) = unbounded::<i32>();
|
|
// let (_s2, r2) = unbounded::<i32>();
|
|
// let (s3, r3) = unbounded::<()>();
|
|
|
|
// scope.spawn(move |_| {
|
|
// r3.recv().unwrap();
|
|
// drop(s1.clone());
|
|
// assert!(r3.try_recv().is_err());
|
|
// s1.send(1).unwrap();
|
|
// r3.recv().unwrap();
|
|
// });
|
|
|
|
// s3.send(()).unwrap();
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.recv(&r2);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// i if i == oper1 => drop(oper.recv(&r1)),
|
|
// i if i == oper2 => drop(oper.recv(&r2)),
|
|
// _ => unreachable!(),
|
|
// }
|
|
|
|
// s3.send(()).unwrap();
|
|
// })
|
|
// .unwrap();
|
|
// }
|
|
|
|
// #[test]
|
|
// fn cloning2() {
|
|
// let (s1, r1) = unbounded::<()>();
|
|
// let (s2, r2) = unbounded::<()>();
|
|
// let (_s3, _r3) = unbounded::<()>();
|
|
|
|
// scope(|scope| {
|
|
// scope.spawn(move |_| {
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.recv(&r2);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// i if i == oper1 => panic!(),
|
|
// i if i == oper2 => drop(oper.recv(&r2)),
|
|
// _ => unreachable!(),
|
|
// }
|
|
// });
|
|
|
|
// thread::sleep(ms(500));
|
|
// drop(s1.clone());
|
|
// s2.send(()).unwrap();
|
|
// })
|
|
// .unwrap();
|
|
// }
|
|
|
|
// #[test]
|
|
// fn preflight1() {
|
|
// let (s, r) = unbounded();
|
|
// s.send(()).unwrap();
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// i if i == oper1 => drop(oper.recv(&r)),
|
|
// _ => unreachable!(),
|
|
// }
|
|
// }
|
|
|
|
// #[test]
|
|
// fn preflight2() {
|
|
// let (s, r) = unbounded();
|
|
// drop(s.clone());
|
|
// s.send(()).unwrap();
|
|
// drop(s);
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// i if i == oper1 => assert_eq!(oper.recv(&r), Ok(())),
|
|
// _ => unreachable!(),
|
|
// }
|
|
|
|
// assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected));
|
|
// }
|
|
|
|
// #[test]
|
|
// fn preflight3() {
|
|
// let (s, r) = unbounded();
|
|
// drop(s.clone());
|
|
// s.send(()).unwrap();
|
|
// drop(s);
|
|
// r.recv().unwrap();
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// i if i == oper1 => assert!(oper.recv(&r).is_err()),
|
|
// _ => unreachable!(),
|
|
// }
|
|
// }
|
|
|
|
// #[test]
|
|
// fn duplicate_operations() {
|
|
// let (s, r) = unbounded::<i32>();
|
|
// let hit = vec![Cell::new(false); 4];
|
|
|
|
// while hit.iter().map(|h| h.get()).any(|hit| !hit) {
|
|
// let mut sel = Select::new();
|
|
// let oper0 = sel.recv(&r);
|
|
// let oper1 = sel.recv(&r);
|
|
// let oper2 = sel.send(&s);
|
|
// let oper3 = sel.send(&s);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// i if i == oper0 => {
|
|
// assert!(oper.recv(&r).is_ok());
|
|
// hit[0].set(true);
|
|
// }
|
|
// i if i == oper1 => {
|
|
// assert!(oper.recv(&r).is_ok());
|
|
// hit[1].set(true);
|
|
// }
|
|
// i if i == oper2 => {
|
|
// assert!(oper.send(&s, 0).is_ok());
|
|
// hit[2].set(true);
|
|
// }
|
|
// i if i == oper3 => {
|
|
// assert!(oper.send(&s, 0).is_ok());
|
|
// hit[3].set(true);
|
|
// }
|
|
// _ => unreachable!(),
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// #[test]
|
|
// fn nesting() {
|
|
// let (s, r) = unbounded::<i32>();
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.send(&s);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// i if i == oper1 => {
|
|
// assert!(oper.send(&s, 0).is_ok());
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// i if i == oper1 => {
|
|
// assert_eq!(oper.recv(&r), Ok(0));
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.send(&s);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// i if i == oper1 => {
|
|
// assert!(oper.send(&s, 1).is_ok());
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// i if i == oper1 => {
|
|
// assert_eq!(oper.recv(&r), Ok(1));
|
|
// }
|
|
// _ => unreachable!(),
|
|
// }
|
|
// }
|
|
// _ => unreachable!(),
|
|
// }
|
|
// }
|
|
// _ => unreachable!(),
|
|
// }
|
|
// }
|
|
// _ => unreachable!(),
|
|
// }
|
|
// }
|
|
|
|
// #[test]
|
|
// fn stress_recv() {
|
|
// const COUNT: usize = 10_000;
|
|
|
|
// let (s1, r1) = unbounded();
|
|
// let (s2, r2) = bounded(5);
|
|
// let (s3, r3) = bounded(100);
|
|
|
|
// scope(|scope| {
|
|
// scope.spawn(|_| {
|
|
// for i in 0..COUNT {
|
|
// s1.send(i).unwrap();
|
|
// r3.recv().unwrap();
|
|
|
|
// s2.send(i).unwrap();
|
|
// r3.recv().unwrap();
|
|
// }
|
|
// });
|
|
|
|
// for i in 0..COUNT {
|
|
// for _ in 0..2 {
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.recv(&r2);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// ix if ix == oper1 => assert_eq!(oper.recv(&r1), Ok(i)),
|
|
// ix if ix == oper2 => assert_eq!(oper.recv(&r2), Ok(i)),
|
|
// _ => unreachable!(),
|
|
// }
|
|
|
|
// s3.send(()).unwrap();
|
|
// }
|
|
// }
|
|
// })
|
|
// .unwrap();
|
|
// }
|
|
|
|
// #[test]
|
|
// fn stress_send() {
|
|
// const COUNT: usize = 10_000;
|
|
|
|
// let (s1, r1) = bounded(0);
|
|
// let (s2, r2) = bounded(0);
|
|
// let (s3, r3) = bounded(100);
|
|
|
|
// scope(|scope| {
|
|
// scope.spawn(|_| {
|
|
// for i in 0..COUNT {
|
|
// assert_eq!(r1.recv().unwrap(), i);
|
|
// assert_eq!(r2.recv().unwrap(), i);
|
|
// r3.recv().unwrap();
|
|
// }
|
|
// });
|
|
|
|
// for i in 0..COUNT {
|
|
// for _ in 0..2 {
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.send(&s1);
|
|
// let oper2 = sel.send(&s2);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// ix if ix == oper1 => assert!(oper.send(&s1, i).is_ok()),
|
|
// ix if ix == oper2 => assert!(oper.send(&s2, i).is_ok()),
|
|
// _ => unreachable!(),
|
|
// }
|
|
// }
|
|
// s3.send(()).unwrap();
|
|
// }
|
|
// })
|
|
// .unwrap();
|
|
// }
|
|
|
|
// #[test]
|
|
// fn stress_mixed() {
|
|
// const COUNT: usize = 10_000;
|
|
|
|
// let (s1, r1) = bounded(0);
|
|
// let (s2, r2) = bounded(0);
|
|
// let (s3, r3) = bounded(100);
|
|
|
|
// scope(|scope| {
|
|
// scope.spawn(|_| {
|
|
// for i in 0..COUNT {
|
|
// s1.send(i).unwrap();
|
|
// assert_eq!(r2.recv().unwrap(), i);
|
|
// r3.recv().unwrap();
|
|
// }
|
|
// });
|
|
|
|
// for i in 0..COUNT {
|
|
// for _ in 0..2 {
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.send(&s2);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// ix if ix == oper1 => assert_eq!(oper.recv(&r1), Ok(i)),
|
|
// ix if ix == oper2 => assert!(oper.send(&s2, i).is_ok()),
|
|
// _ => unreachable!(),
|
|
// }
|
|
// }
|
|
// s3.send(()).unwrap();
|
|
// }
|
|
// })
|
|
// .unwrap();
|
|
// }
|
|
|
|
// #[test]
|
|
// fn stress_timeout_two_threads() {
|
|
// const COUNT: usize = 20;
|
|
|
|
// let (s, r) = bounded(2);
|
|
|
|
// scope(|scope| {
|
|
// scope.spawn(|_| {
|
|
// for i in 0..COUNT {
|
|
// if i % 2 == 0 {
|
|
// thread::sleep(ms(500));
|
|
// }
|
|
|
|
// let done = false;
|
|
// while !done {
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.send(&s);
|
|
// let oper = sel.select_timeout(ms(100));
|
|
// match oper {
|
|
// Err(_) => {}
|
|
// Ok(oper) => match oper.index() {
|
|
// ix if ix == oper1 => {
|
|
// assert!(oper.send(&s, i).is_ok());
|
|
// break;
|
|
// }
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
// }
|
|
// }
|
|
// });
|
|
|
|
// scope.spawn(|_| {
|
|
// for i in 0..COUNT {
|
|
// if i % 2 == 0 {
|
|
// thread::sleep(ms(500));
|
|
// }
|
|
|
|
// let mut done = false;
|
|
// while !done {
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r);
|
|
// let oper = sel.select_timeout(ms(100));
|
|
// match oper {
|
|
// Err(_) => {}
|
|
// Ok(oper) => match oper.index() {
|
|
// ix if ix == oper1 => {
|
|
// assert_eq!(oper.recv(&r), Ok(i));
|
|
// done = true;
|
|
// }
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
// }
|
|
// }
|
|
// });
|
|
// })
|
|
// .unwrap();
|
|
// }
|
|
|
|
// #[test]
|
|
// fn send_recv_same_channel() {
|
|
// let (s, r) = bounded::<i32>(0);
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.send(&s);
|
|
// let oper2 = sel.recv(&r);
|
|
// let oper = sel.select_timeout(ms(100));
|
|
// match oper {
|
|
// Err(_) => {}
|
|
// Ok(oper) => match oper.index() {
|
|
// ix if ix == oper1 => panic!(),
|
|
// ix if ix == oper2 => panic!(),
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
|
|
// let (s, r) = unbounded::<i32>();
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.send(&s);
|
|
// let oper2 = sel.recv(&r);
|
|
// let oper = sel.select_timeout(ms(100));
|
|
// match oper {
|
|
// Err(_) => panic!(),
|
|
// Ok(oper) => match oper.index() {
|
|
// ix if ix == oper1 => assert!(oper.send(&s, 0).is_ok()),
|
|
// ix if ix == oper2 => panic!(),
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
// }
|
|
|
|
// #[test]
|
|
// fn matching() {
|
|
// const THREADS: usize = 44;
|
|
|
|
// let (s, r) = &bounded::<usize>(0);
|
|
|
|
// scope(|scope| {
|
|
// for i in 0..THREADS {
|
|
// scope.spawn(move |_| {
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r);
|
|
// let oper2 = sel.send(&s);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// ix if ix == oper1 => assert_ne!(oper.recv(&r), Ok(i)),
|
|
// ix if ix == oper2 => assert!(oper.send(&s, i).is_ok()),
|
|
// _ => unreachable!(),
|
|
// }
|
|
// });
|
|
// }
|
|
// })
|
|
// .unwrap();
|
|
|
|
// assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
|
|
// }
|
|
|
|
// #[test]
|
|
// fn matching_with_leftover() {
|
|
// const THREADS: usize = 55;
|
|
|
|
// let (s, r) = &bounded::<usize>(0);
|
|
|
|
// scope(|scope| {
|
|
// for i in 0..THREADS {
|
|
// scope.spawn(move |_| {
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r);
|
|
// let oper2 = sel.send(&s);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// ix if ix == oper1 => assert_ne!(oper.recv(&r), Ok(i)),
|
|
// ix if ix == oper2 => assert!(oper.send(&s, i).is_ok()),
|
|
// _ => unreachable!(),
|
|
// }
|
|
// });
|
|
// }
|
|
// s.send(!0).unwrap();
|
|
// })
|
|
// .unwrap();
|
|
|
|
// assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
|
|
// }
|
|
|
|
// #[test]
|
|
// fn channel_through_channel() {
|
|
// const COUNT: usize = 1000;
|
|
|
|
// type T = Box<dyn Any + Send>;
|
|
|
|
// for cap in 0..3 {
|
|
// let (s, r) = bounded::<T>(cap);
|
|
|
|
// scope(|scope| {
|
|
// scope.spawn(move |_| {
|
|
// let mut s = s;
|
|
|
|
// for _ in 0..COUNT {
|
|
// let (new_s, new_r) = bounded(cap);
|
|
// let new_r: T = Box::new(Some(new_r));
|
|
|
|
// {
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.send(&s);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// ix if ix == oper1 => assert!(oper.send(&s, new_r).is_ok()),
|
|
// _ => unreachable!(),
|
|
// }
|
|
// }
|
|
|
|
// s = new_s;
|
|
// }
|
|
// });
|
|
|
|
// scope.spawn(move |_| {
|
|
// let mut r = r;
|
|
|
|
// for _ in 0..COUNT {
|
|
// let new = {
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// ix if ix == oper1 => oper
|
|
// .recv(&r)
|
|
// .unwrap()
|
|
// .downcast_mut::<Option<Receiver<T>>>()
|
|
// .unwrap()
|
|
// .take()
|
|
// .unwrap(),
|
|
// _ => unreachable!(),
|
|
// }
|
|
// };
|
|
// r = new;
|
|
// }
|
|
// });
|
|
// })
|
|
// .unwrap();
|
|
// }
|
|
// }
|
|
|
|
// #[test]
|
|
// fn linearizable_try() {
|
|
// const COUNT: usize = 100_000;
|
|
|
|
// for step in 0..2 {
|
|
// let (start_s, start_r) = bounded::<()>(0);
|
|
// let (end_s, end_r) = bounded::<()>(0);
|
|
|
|
// let ((s1, r1), (s2, r2)) = if step == 0 {
|
|
// (bounded::<i32>(1), bounded::<i32>(1))
|
|
// } else {
|
|
// (unbounded::<i32>(), unbounded::<i32>())
|
|
// };
|
|
|
|
// scope(|scope| {
|
|
// scope.spawn(|_| {
|
|
// for _ in 0..COUNT {
|
|
// start_s.send(()).unwrap();
|
|
|
|
// s1.send(1).unwrap();
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.recv(&r2);
|
|
// let oper = sel.try_select();
|
|
// match oper {
|
|
// Err(_) => unreachable!(),
|
|
// Ok(oper) => match oper.index() {
|
|
// ix if ix == oper1 => assert!(oper.recv(&r1).is_ok()),
|
|
// ix if ix == oper2 => assert!(oper.recv(&r2).is_ok()),
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
|
|
// end_s.send(()).unwrap();
|
|
// let _ = r2.try_recv();
|
|
// }
|
|
// });
|
|
|
|
// for _ in 0..COUNT {
|
|
// start_r.recv().unwrap();
|
|
|
|
// s2.send(1).unwrap();
|
|
// let _ = r1.try_recv();
|
|
|
|
// end_r.recv().unwrap();
|
|
// }
|
|
// })
|
|
// .unwrap();
|
|
// }
|
|
// }
|
|
|
|
// #[test]
|
|
// fn linearizable_timeout() {
|
|
// const COUNT: usize = 100_000;
|
|
|
|
// for step in 0..2 {
|
|
// let (start_s, start_r) = bounded::<()>(0);
|
|
// let (end_s, end_r) = bounded::<()>(0);
|
|
|
|
// let ((s1, r1), (s2, r2)) = if step == 0 {
|
|
// (bounded::<i32>(1), bounded::<i32>(1))
|
|
// } else {
|
|
// (unbounded::<i32>(), unbounded::<i32>())
|
|
// };
|
|
|
|
// scope(|scope| {
|
|
// scope.spawn(|_| {
|
|
// for _ in 0..COUNT {
|
|
// start_s.send(()).unwrap();
|
|
|
|
// s1.send(1).unwrap();
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.recv(&r2);
|
|
// let oper = sel.select_timeout(ms(0));
|
|
// match oper {
|
|
// Err(_) => unreachable!(),
|
|
// Ok(oper) => match oper.index() {
|
|
// ix if ix == oper1 => assert!(oper.recv(&r1).is_ok()),
|
|
// ix if ix == oper2 => assert!(oper.recv(&r2).is_ok()),
|
|
// _ => unreachable!(),
|
|
// },
|
|
// }
|
|
|
|
// end_s.send(()).unwrap();
|
|
// let _ = r2.try_recv();
|
|
// }
|
|
// });
|
|
|
|
// for _ in 0..COUNT {
|
|
// start_r.recv().unwrap();
|
|
|
|
// s2.send(1).unwrap();
|
|
// let _ = r1.try_recv();
|
|
|
|
// end_r.recv().unwrap();
|
|
// }
|
|
// })
|
|
// .unwrap();
|
|
// }
|
|
// }
|
|
|
|
// #[test]
|
|
// fn fairness1() {
|
|
// const COUNT: usize = 10_000;
|
|
|
|
// let (s1, r1) = bounded::<()>(COUNT);
|
|
// let (s2, r2) = unbounded::<()>();
|
|
|
|
// for _ in 0..COUNT {
|
|
// s1.send(()).unwrap();
|
|
// s2.send(()).unwrap();
|
|
// }
|
|
|
|
// let hits = vec![Cell::new(0usize); 4];
|
|
// for _ in 0..COUNT {
|
|
// let after = after(ms(0));
|
|
// let tick = tick(ms(0));
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.recv(&r2);
|
|
// let oper3 = sel.recv(&after);
|
|
// let oper4 = sel.recv(&tick);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// i if i == oper1 => {
|
|
// oper.recv(&r1).unwrap();
|
|
// hits[0].set(hits[0].get() + 1);
|
|
// }
|
|
// i if i == oper2 => {
|
|
// oper.recv(&r2).unwrap();
|
|
// hits[1].set(hits[1].get() + 1);
|
|
// }
|
|
// i if i == oper3 => {
|
|
// oper.recv(&after).unwrap();
|
|
// hits[2].set(hits[2].get() + 1);
|
|
// }
|
|
// i if i == oper4 => {
|
|
// oper.recv(&tick).unwrap();
|
|
// hits[3].set(hits[3].get() + 1);
|
|
// }
|
|
// _ => unreachable!(),
|
|
// }
|
|
// }
|
|
// assert!(hits.iter().all(|x| x.get() >= COUNT / hits.len() / 2));
|
|
// }
|
|
|
|
// #[test]
|
|
// fn fairness2() {
|
|
// const COUNT: usize = 10_000;
|
|
|
|
// let (s1, r1) = unbounded::<()>();
|
|
// let (s2, r2) = bounded::<()>(1);
|
|
// let (s3, r3) = bounded::<()>(0);
|
|
|
|
// scope(|scope| {
|
|
// scope.spawn(|_| {
|
|
// for _ in 0..COUNT {
|
|
// let mut sel = Select::new();
|
|
// let mut oper1 = None;
|
|
// let mut oper2 = None;
|
|
// if s1.is_empty() {
|
|
// oper1 = Some(sel.send(&s1));
|
|
// }
|
|
// if s2.is_empty() {
|
|
// oper2 = Some(sel.send(&s2));
|
|
// }
|
|
// let oper3 = sel.send(&s3);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// i if Some(i) == oper1 => assert!(oper.send(&s1, ()).is_ok()),
|
|
// i if Some(i) == oper2 => assert!(oper.send(&s2, ()).is_ok()),
|
|
// i if i == oper3 => assert!(oper.send(&s3, ()).is_ok()),
|
|
// _ => unreachable!(),
|
|
// }
|
|
// }
|
|
// });
|
|
|
|
// let hits = vec![Cell::new(0usize); 3];
|
|
// for _ in 0..COUNT {
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.recv(&r2);
|
|
// let oper3 = sel.recv(&r3);
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// i if i == oper1 => {
|
|
// oper.recv(&r1).unwrap();
|
|
// hits[0].set(hits[0].get() + 1);
|
|
// }
|
|
// i if i == oper2 => {
|
|
// oper.recv(&r2).unwrap();
|
|
// hits[1].set(hits[1].get() + 1);
|
|
// }
|
|
// i if i == oper3 => {
|
|
// oper.recv(&r3).unwrap();
|
|
// hits[2].set(hits[2].get() + 1);
|
|
// }
|
|
// _ => unreachable!(),
|
|
// }
|
|
// }
|
|
// assert!(hits.iter().all(|x| x.get() >= COUNT / hits.len() / 50));
|
|
// })
|
|
// .unwrap();
|
|
// }
|
|
|
|
// #[test]
|
|
// fn sync_and_clone() {
|
|
// const THREADS: usize = 20;
|
|
|
|
// let (s, r) = &bounded::<usize>(0);
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r);
|
|
// let oper2 = sel.send(&s);
|
|
// let sel = &sel;
|
|
|
|
// scope(|scope| {
|
|
// for i in 0..THREADS {
|
|
// scope.spawn(move |_| {
|
|
// let mut sel = sel.clone();
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// ix if ix == oper1 => assert_ne!(oper.recv(&r), Ok(i)),
|
|
// ix if ix == oper2 => assert!(oper.send(&s, i).is_ok()),
|
|
// _ => unreachable!(),
|
|
// }
|
|
// });
|
|
// }
|
|
// })
|
|
// .unwrap();
|
|
|
|
// assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
|
|
// }
|
|
|
|
// #[test]
|
|
// fn send_and_clone() {
|
|
// const THREADS: usize = 20;
|
|
|
|
// let (s, r) = &bounded::<usize>(0);
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r);
|
|
// let oper2 = sel.send(&s);
|
|
|
|
// scope(|scope| {
|
|
// for i in 0..THREADS {
|
|
// let mut sel = sel.clone();
|
|
// scope.spawn(move |_| {
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// ix if ix == oper1 => assert_ne!(oper.recv(&r), Ok(i)),
|
|
// ix if ix == oper2 => assert!(oper.send(&s, i).is_ok()),
|
|
// _ => unreachable!(),
|
|
// }
|
|
// });
|
|
// }
|
|
// })
|
|
// .unwrap();
|
|
|
|
// assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
|
|
// }
|
|
|
|
// #[test]
|
|
// fn reuse() {
|
|
// const COUNT: usize = 10_000;
|
|
|
|
// let (s1, r1) = bounded(0);
|
|
// let (s2, r2) = bounded(0);
|
|
// let (s3, r3) = bounded(100);
|
|
|
|
// scope(|scope| {
|
|
// scope.spawn(|_| {
|
|
// for i in 0..COUNT {
|
|
// s1.send(i).unwrap();
|
|
// assert_eq!(r2.recv().unwrap(), i);
|
|
// r3.recv().unwrap();
|
|
// }
|
|
// });
|
|
|
|
// let mut sel = Select::new();
|
|
// let oper1 = sel.recv(&r1);
|
|
// let oper2 = sel.send(&s2);
|
|
|
|
// for i in 0..COUNT {
|
|
// for _ in 0..2 {
|
|
// let oper = sel.select();
|
|
// match oper.index() {
|
|
// ix if ix == oper1 => assert_eq!(oper.recv(&r1), Ok(i)),
|
|
// ix if ix == oper2 => assert!(oper.send(&s2, i).is_ok()),
|
|
// _ => unreachable!(),
|
|
// }
|
|
// }
|
|
// s3.send(()).unwrap();
|
|
// }
|
|
// })
|
|
// .unwrap();
|
|
// }
|