Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


SSL select.rs   Sprache: unbekannt

 
Spracherkennung für: .rs vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

//! Tests for channel selection using the `Select` struct.

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() {
    #[cfg(miri)]
    const COUNT: usize = 50;
    #[cfg(not(miri))]
    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() {
    #[cfg(miri)]
    const COUNT: usize = 50;
    #[cfg(not(miri))]
    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() {
    #[cfg(miri)]
    const COUNT: usize = 100;
    #[cfg(not(miri))]
    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));
                }

                loop {
                    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));
                }

                loop {
                    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));
                                break;
                            }
                            _ => 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() {
    #[cfg(miri)]
    const COUNT: usize = 50;
    #[cfg(not(miri))]
    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() {
    #[cfg(miri)]
    const COUNT: usize = 50;
    #[cfg(not(miri))]
    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() {
    #[cfg(miri)]
    const COUNT: usize = 50;
    #[cfg(not(miri))]
    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() {
    #[cfg(miri)]
    const COUNT: usize = 50;
    #[cfg(not(miri))]
    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() {
    #[cfg(miri)]
    const COUNT: usize = 50;
    #[cfg(not(miri))]
    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() {
    #[cfg(miri)]
    const COUNT: usize = 50;
    #[cfg(not(miri))]
    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();
}

[ Verzeichnis aufwärts0.55unsichere Verbindung  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge