#[test] fn concurrent_create_with_clear() {
run_model("concurrent_create_with_clear", || { let pool: Arc<Pool<DontDropMe>> = Arc::new(Pool::new()); let pair = Arc::new((Mutex::new(None), Condvar::new()));
let (item1, value) = DontDropMe::new(1); let idx1 = pool
.create_with(move |item| *item = value)
.expect("create_with"); let p = pool.clone(); let pair2 = pair.clone(); let test_value = item1.clone(); let t1 = thread::spawn(move || { let (lock, cvar) = &*pair2;
test_println!("-> making get request");
assert_eq!(p.get(idx1).unwrap().0.id, test_value.id); letmut next = lock.lock().unwrap();
*next = Some(());
cvar.notify_one();
});
test_println!("-> making get request"); let guard = pool.get(idx1);
let (lock, cvar) = &*pair; letmut next = lock.lock().unwrap(); // wait until we have a guard on the other thread. while next.is_none() {
next = cvar.wait(next).unwrap();
} // the item should be marked (clear returns true)...
assert!(pool.clear(idx1)); // ...but the value shouldn't be removed yet.
item1.assert_not_clear();
t1.join().expect("thread 1 unable to join");
drop(guard);
item1.assert_clear();
})
}
#[test] fn racy_clear() {
run_model("racy_clear", || { let pool = Arc::new(Pool::new()); let (item, value) = DontDropMe::new(1);
let idx = pool
.create_with(move |item| *item = value)
.expect("create_with");
assert_eq!(pool.get(idx).unwrap().0.id, item.id);
let p = pool.clone(); let t2 = thread::spawn(move || p.clear(idx)); let r1 = pool.clear(idx); let r2 = t2.join().expect("thread 2 should not panic");
test_println!("r1: {}, r2: {}", r1, r2);
assert!(
!(r1 && r2), "Both threads should not have cleared the value"
);
assert!(r1 || r2, "One thread should have removed the value");
assert!(pool.get(idx).is_none());
item.assert_clear();
})
}
#[test] fn clear_local_and_reuse() {
run_model("take_remote_and_reuse", || { let pool = Arc::new(Pool::new_with_config::<TinyConfig>());
let idx1 = pool
.create_with(|item: &mut String| {
item.push_str("hello world");
})
.expect("create_with"); let idx2 = pool
.create_with(|item| item.push_str("foo"))
.expect("create_with"); let idx3 = pool
.create_with(|item| item.push_str("bar"))
.expect("create_with");
let first = idx1 & (!crate::page::slot::Generation::<TinyConfig>::MASK);
assert!(pool.clear(idx1));
let idx1 = pool
.create_with(move |item| item.push_str("h"))
.expect("create_with");
let second = idx1 & (!crate::page::slot::Generation::<TinyConfig>::MASK);
assert_eq!(first, second);
assert!(pool.get(idx1).unwrap().capacity() >= 11);
})
}
#[test] fn create_mut_guard_prevents_access() {
run_model("create_mut_guard_prevents_access", || { let pool = Arc::new(Pool::<String>::new()); let guard = pool.create().unwrap(); let key: usize = guard.key();
#[test] fn ownedref_send_out_of_local() {
run_model("ownedref_send_out_of_local", || { let pool = Arc::new(Pool::<alloc::Track<String>>::new()); let key1 = pool
.create_with(|item| item.get_mut().push_str("hello"))
.expect("create item 1"); let key2 = pool
.create_with(|item| item.get_mut().push_str("goodbye"))
.expect("create item 2");
let item1 = pool.clone().get_owned(key1).expect("get key1"); let item2 = pool.clone().get_owned(key2).expect("get key2"); let pool2 = pool.clone();
#[test] fn ownedrefs_outlive_pool() {
run_model("ownedrefs_outlive_pool", || { let pool = Arc::new(Pool::<alloc::Track<String>>::new()); let key1 = pool
.create_with(|item| item.get_mut().push_str("hello"))
.expect("create item 1"); let key2 = pool
.create_with(|item| item.get_mut().push_str("goodbye"))
.expect("create item 2");
let item1_1 = pool.clone().get_owned(key1).expect("get key1"); let item1_2 = pool.clone().get_owned(key1).expect("get key1 again"); let item2 = pool.clone().get_owned(key2).expect("get key2");
drop(pool);
let t1 = thread::spawn(move || {
assert_eq!(item1_1.get_ref(), &String::from("hello"));
drop(item1_1);
});
let t2 = thread::spawn(move || {
assert_eq!(item2.get_ref(), &String::from("goodbye"));
drop(item2);
});
#[test] fn ownedref_ping_pong() {
run_model("ownedref_ping_pong", || { let pool = Arc::new(Pool::<alloc::Track<String>>::new()); let key1 = pool
.create_with(|item| item.get_mut().push_str("hello"))
.expect("create item 1"); let key2 = pool
.create_with(|item| item.get_mut().push_str("world"))
.expect("create item 2");
let item1 = pool.clone().get_owned(key1).expect("get key1"); let pool2 = pool.clone(); let pool3 = pool.clone();
#[test] fn ownedref_drop_from_other_threads() {
run_model("ownedref_drop_from_other_threads", || { let pool = Arc::new(Pool::<alloc::Track<String>>::new()); let key1 = pool
.create_with(|item| item.get_mut().push_str("hello"))
.expect("create item 1"); let item1 = pool.clone().get_owned(key1).expect("get key1");
let pool2 = pool.clone();
let t1 = thread::spawn(move || { let pool = pool2.clone(); let key2 = pool
.create_with(|item| item.get_mut().push_str("goodbye"))
.expect("create item 1"); let item2 = pool.clone().get_owned(key2).expect("get key1"); let t2 = thread::spawn(move || {
assert_eq!(item2.get_ref(), &String::from("goodbye"));
test_dbg!(pool2.clear(key1));
drop(item2)
});
assert_eq!(item1.get_ref(), &String::from("hello"));
test_dbg!(pool.clear(key2));
drop(item1);
(t2, key2)
});
let (t2, key2) = t1.join().unwrap();
test_dbg!(pool.get(key1));
test_dbg!(pool.get(key2));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.