`Once::call_once` doesn't guarantee that the given closure is called only if this is the first time `call_once` has been called.
usamoi opened this issue · 2 comments
usamoi commented
This test fails with a certain probability.
// insert this in once.rs:684
#[test]
fn extra() {
use std::sync::Arc;
use std::sync::atomic::AtomicUsize;
use std::time::Duration;
let share = Arc::new(AtomicUsize::new(0));
let once = Arc::new(Once::<_, Spin>::new());
let mut hs = Vec::new();
for _ in 0..10 {
let h = thread::spawn({
let share = share.clone();
let once = once.clone();
move || {
thread::sleep(Duration::from_millis(10));
once.call_once(|| {
share.fetch_add(1, Ordering::SeqCst);
});
}
});
hs.push(h);
}
for h in hs {
let _ = h.join();
}
assert_eq!(1, share.load(Ordering::SeqCst));
}
usamoi commented
A typo in https://github.com/mvdnes/spin-rs/blob/master/src/once.rs#L113 makes this bug.
I have made a pull request (#118) to fix it.
zesterer commented
This has now been included in the 0.9.3
release.