molframe-core 0.1.0

Core types, storage and analysis contracts for molframe
Documentation
use super::*;
use std::sync::atomic::{AtomicUsize, Ordering};

#[test]
fn simultaneous_callers_share_one_admission_ceiling() {
    let admission = Admission::new(4);
    let cancellation = CancellationToken::default();
    let active = AtomicUsize::new(0);
    let peak = AtomicUsize::new(0);
    std::thread::scope(|scope| {
        for _ in 0..8 {
            scope.spawn(|| {
                for _ in 0..10 {
                    let guard = admission.acquire(3, &cancellation).expect("admission");
                    let current = active.fetch_add(guard.count, Ordering::SeqCst) + guard.count;
                    peak.fetch_max(current, Ordering::SeqCst);
                    std::thread::yield_now();
                    active.fetch_sub(guard.count, Ordering::SeqCst);
                    drop(guard);
                }
            });
        }
    });
    assert!(peak.load(Ordering::SeqCst) <= 4);
    assert_eq!(*admission.used.lock().expect("counter"), 0);
}

#[test]
fn cancellation_interrupts_a_caller_waiting_for_admission() {
    let admission = Admission::new(1);
    let cancellation = CancellationToken::default();
    let _guard = admission
        .acquire(1, &cancellation)
        .expect("first admission");
    std::thread::scope(|scope| {
        let waiting = scope.spawn(|| admission.acquire(1, &cancellation).is_none());
        cancellation.cancel();
        assert!(waiting.join().expect("waiting caller"));
    });
}

#[test]
fn unwinding_releases_admission_and_nesting_state() {
    let admission = Admission::new(2);
    let cancellation = CancellationToken::default();
    let failed = std::panic::catch_unwind(|| {
        let (_depth, nested) = ExecutionDepth::enter();
        assert!(!nested);
        let _guard = admission.acquire(2, &cancellation).expect("admission");
        panic!("injected failure");
    });
    assert!(failed.is_err());
    let (_depth, nested) = ExecutionDepth::enter();
    assert!(!nested);
    assert_eq!(
        admission.acquire(2, &cancellation).expect("released").count,
        2
    );
}