更新libclamav库1.0.0版本
This commit is contained in:
103
clamav/libclamav_rust/.cargo/vendor/scoped_threadpool/tests/threads-living-too-long-demo.rs
vendored
Normal file
103
clamav/libclamav_rust/.cargo/vendor/scoped_threadpool/tests/threads-living-too-long-demo.rs
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
extern crate scoped_threadpool;
|
||||
|
||||
use scoped_threadpool::Pool;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT};
|
||||
use std::panic::AssertUnwindSafe;
|
||||
|
||||
// The representation invariant for PositivelyAtomic is that it is
|
||||
// always a positive integer. When we drop it, we store zero in
|
||||
// its value; but one should never observe that.
|
||||
pub struct PositivelyAtomic(AtomicUsize);
|
||||
impl Drop for PositivelyAtomic {
|
||||
fn drop(&mut self) {
|
||||
// Since we are being dropped, we will now break the
|
||||
// representation invariant. (And then clients will
|
||||
// subsequently observe that breakage.)
|
||||
self.0.store(0, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
impl PositivelyAtomic {
|
||||
pub fn new(x: usize) -> PositivelyAtomic {
|
||||
assert!(x > 0);
|
||||
PositivelyAtomic(AtomicUsize::new(x))
|
||||
}
|
||||
// Assuming the representation invariant holds, this should
|
||||
// always return a positive value.
|
||||
pub fn load(&self) -> usize {
|
||||
self.0.load(Ordering::Relaxed)
|
||||
}
|
||||
pub fn cas(&self, old: usize, new: usize) -> usize {
|
||||
assert!(new > 0);
|
||||
self.0.compare_and_swap(old, new, Ordering::Relaxed)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demo_stack_allocated() {
|
||||
static SAW_ZERO: AtomicBool = ATOMIC_BOOL_INIT;
|
||||
for _i in 0..100 {
|
||||
let saw_zero = &AssertUnwindSafe(&SAW_ZERO);
|
||||
let _p = ::std::panic::catch_unwind(move || {
|
||||
let p = PositivelyAtomic::new(1);
|
||||
kernel(&p, saw_zero);
|
||||
});
|
||||
|
||||
if saw_zero.load(Ordering::Relaxed) {
|
||||
panic!("demo_stack_allocated saw zero!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demo_heap_allocated() {
|
||||
static SAW_ZERO: AtomicBool = ATOMIC_BOOL_INIT;
|
||||
for i in 0..100 {
|
||||
let saw_zero = &AssertUnwindSafe(&SAW_ZERO);
|
||||
let _p = ::std::panic::catch_unwind(move || {
|
||||
let mut v = Vec::with_capacity((i % 5)*1024 + i);
|
||||
v.push(PositivelyAtomic::new(1));
|
||||
kernel(&v[0], saw_zero);
|
||||
});
|
||||
|
||||
if saw_zero.load(Ordering::Relaxed) {
|
||||
panic!("demo_heap_allocated saw zero!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn kernel(r: &PositivelyAtomic, saw_zero: &AtomicBool) {
|
||||
// Create a threadpool holding 4 threads
|
||||
let mut pool = Pool::new(4);
|
||||
|
||||
// Use the threads as scoped threads that can
|
||||
// reference anything outside this closure
|
||||
pool.scoped(|scope| {
|
||||
// Create references to each element in the vector ...
|
||||
for _ in 0..4 {
|
||||
scope.execute(move || {
|
||||
for _ in 0..100000 {
|
||||
let v = r.load();
|
||||
if v == 0 {
|
||||
saw_zero.store(true, Ordering::Relaxed);
|
||||
panic!("SAW ZERO");
|
||||
}
|
||||
let v_new = (v % 100) + 1;
|
||||
if v != r.cas(v, v_new) {
|
||||
|
||||
// this is not a true panic condition
|
||||
// in the original scenario.
|
||||
//
|
||||
// it rather is a rare event, and I want to
|
||||
// emulate a rare panic occurring from one
|
||||
// thread (and then see how the overall
|
||||
// computation proceeds from there).
|
||||
panic!("interference");
|
||||
} else {
|
||||
// incremented successfully
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user