bombs 0.2.1

Efficient single-producer multi-consumer channel types.
Documentation
#[test]
fn threaded_unchecked_u32() {
    use bombs::blocking::Bomb;
    use loom::{ thread, hint };

    loom::model(|| {
        let (fuse, bomb) = Bomb::new();

        let handle = {
            let bomb_clone = bomb.clone();

            let h = thread::spawn(move || {
                let bomb = bomb_clone;

                thread::yield_now();

                // Do nothing, but drop in here.
                // Loom is exhaustive so this is to test
                // what happens when an unsynchronised bomb
                // is the final to drop.
                drop(bomb);
            });

            // Idk why but this casues issues otherwise.
            drop(bomb);

            h
        };

        let flame = fuse.light(5_u32);

        flame.wait_for_extinguish();

        handle.join().unwrap();
    });
}

#[test]
fn threaded_multi_u32() {
    use bombs::blocking::MultiBomb;
    use loom::thread;

    loom::model(|| {
        let (mut fuse, bomb) = MultiBomb::new();

        let handle = {
            let mut bomb_clone = bomb.clone();

            let h = thread::spawn(move || {
                let value = bomb_clone.wait_for_explosion();
                assert_eq!(value, 5);
                let value = bomb_clone.wait_for_explosion();
                assert_eq!(value, 24);
            });

            // Idk why but this casues issues otherwise.
            drop(bomb);

            h
        };

        let flame = fuse.light(5_u32);

        flame.wait_for_extinguish();
        assert!(flame.extinguished());

        let flame = fuse.light(24);

        flame.wait_for_extinguish();
        assert!(flame.extinguished());

        handle.join().unwrap();
    });
}

#[test]
fn threaded_u32() {
    use bombs::blocking::Bomb;
    use loom::thread;

    loom::model(|| {
        let (fuse, bomb) = Bomb::new();

        let handle = {
            let bomb_clone = bomb.clone();

            let h = thread::spawn(move || {
                let value = bomb_clone.wait_for_explosion();
                assert_eq!(*value, 5);
            });

            // Idk why but this casues issues otherwise.
            drop(bomb);

            h
        };

        let flame = fuse.light(5_u32);

        flame.wait_for_extinguish();
        assert!(flame.extinguished());

        handle.join().unwrap();
    });
}

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

    loom::model(|| {
        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.wait_for_explosion(), &7);

        assert!(!flame.extinguished());

        drop(bomb_clone);
        drop(bomb);

        assert!(flame.extinguished());
    });
}

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

    loom::model(|| {
        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);
    });
}