bombs 0.2.1

Efficient single-producer multi-consumer channel types.
Documentation
#[test]
fn threaded_multi_u32() {
    use bombs::MultiBomb;
    use std::{ thread, hint };

    let (mut fuse, bomb) = MultiBomb::new();

    let handles = (0..2).into_iter().map(move |_| {
        let mut bomb_clone = bomb.clone();

        thread::spawn(move || {
            let value = loop {
                match bomb_clone.exploded() {
                    Some(v) => break v,
                    None => hint::spin_loop(),
                }
            };
            assert_eq!(value, 5);

            let value = loop {
                match bomb_clone.exploded() {
                    Some(v) => break v,
                    None => hint::spin_loop(),
                }
            };
            assert_eq!(value, 24);
        })
    }).collect::<Vec<_>>();

    let flame = fuse.light(5_u32);

    while !flame.extinguished() { hint::spin_loop(); }

    let flame = fuse.light(24);

    while !flame.extinguished() { hint::spin_loop(); }

    handles.into_iter().for_each(|h| h.join().unwrap());
}

#[test]
fn threaded_u32() {
    use bombs::Bomb;
    use std::{ thread, hint };

    let (fuse, bomb) = Bomb::new();

    let handles = (0..2).into_iter().map(move |_| {
        let bomb_clone = bomb.clone();

        thread::spawn(move || {
            while let None = bomb_clone.exploded() { hint::spin_loop(); }

            assert_eq!(bomb_clone.exploded(), Some(&5));
        })
    }).collect::<Vec<_>>();

    let flame = fuse.light(5_u32);

    while !flame.extinguished() { hint::spin_loop() }

    handles.into_iter().for_each(|h| h.join().unwrap());
}

#[test]
fn simple_u32() {
    use bombs::Bomb;

    let (fuse, bomb) = Bomb::new();

    let bomb_clone = bomb.clone();

    assert_eq!(bomb.exploded(), None);
    assert_eq!(bomb_clone.exploded(), None);

    let flame = fuse.light(7_u32);

    assert_eq!(bomb.exploded(), Some(&7));
    assert_eq!(bomb_clone.exploded(), Some(&7));

    assert!(!flame.extinguished());

    drop(bomb_clone);
    drop(bomb);

    assert!(flame.extinguished());
}

#[test]
fn empty_u32() {
    use bombs::Bomb;

    let (fuse, bomb) = Bomb::<u32>::new();
    let bomb_clone = bomb.clone();

    assert_eq!(bomb.exploded(), None);
    assert_eq!(bomb_clone.exploded(), None);

    let _fuse = std::hint::black_box(fuse);
}

#[test]
fn box_dropped_correctly() {
    use bombs::*;

    let (fuse, bomb) = Bomb::new();

    let bomb_clone = bomb.clone();

    fuse.light(Box::new("Hello world".to_owned()));

    // No double-drop
    assert_eq!(&**bomb.exploded().unwrap(), "Hello world");
    assert_eq!(&**bomb_clone.exploded().unwrap(), "Hello world");
    assert_eq!(&**bomb.exploded().unwrap(), "Hello world");
}

#[test]
fn multi_box_dropped_correctly() {
    use bombs::*;

    let (mut fuse, mut bomb) = MultiBomb::new();

    let mut bomb_clone = bomb.clone();

    fuse.light(Box::new("Hello".to_owned()));
    fuse.light(Box::new(" world".to_owned()));

    // No double-drop
    assert_eq!(&*bomb.exploded().unwrap(), "Hello");
    assert_eq!(&*bomb_clone.exploded().unwrap(), "Hello");
    assert_eq!(&*bomb.exploded().unwrap(), " world");
    assert_eq!(&*bomb_clone.exploded().unwrap(), " world");

    assert_eq!(bomb.exploded(), None);
    assert_eq!(bomb_clone.exploded(), None);
}