Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::sync::{Arc, Mutex};
- struct S {
- val: Option<usize>,
- }
- struct LockedS {
- val: Arc<Mutex<S>>,
- idx: usize,
- }
- struct Pool {
- inner: Mutex<Inner>,
- }
- struct Inner {
- values: Vec<Arc<Mutex<S>>>,
- available: Vec<usize>,
- }
- impl Pool {
- fn new() -> Self {
- let inner = Mutex::new(Inner {
- values: vec![],
- available: vec![],
- });
- Self {inner}
- }
- fn acquire(&self) -> LockedS {
- let mut guard = self.inner.lock().unwrap();
- if let Some(idx) = guard.available.pop() {
- LockedS {
- val: Arc::clone(&guard.values[idx]),
- idx,
- }
- } else {
- let v = Arc::new(Mutex::new(S{val: None}));
- guard.values.push(Arc::clone(&v));
- LockedS {
- val: v,
- idx: guard.values.len() - 1,
- }
- }
- }
- fn release(&self, s: LockedS) {
- let mut guard = self.inner.lock().unwrap();
- assert!(s.idx < guard.values.len());
- guard.available.push(s.idx);
- }
- fn count(&self) -> usize {
- let guard = self.inner.lock().unwrap();
- guard.values.len()
- }
- fn get_s(&self, idx: usize) -> Arc<Mutex<S>> {
- let guard = self.inner.lock().unwrap();
- Arc::clone(&guard.values[idx])
- }
- fn find_valid_s(&self) -> Option<LockedS> {
- let mut idx = usize::max_value();
- for i in 0..self.count() {
- let s = self.get_s(i);
- {
- if let Ok(guard) = s.try_lock() {
- if guard.val.is_some() {
- idx = i;
- break;
- }
- }
- }
- }
- if idx != usize::max_value() {
- Some(LockedS{
- val: self.get_s(idx),
- idx,
- })
- } else {
- None
- }
- }
- }
- fn main() {
- let pool = Pool::new();
- let ctrl = Ctrl {pool_ref: &pool};
- {
- let _s = pool.acquire();
- }
- {
- let s = pool.acquire();
- let mut g = s.val.lock().unwrap();
- g.val = Some(0);
- }
- if let Some(valid_s) = pool.find_valid_s() {
- println!("find valid with index: {}", valid_s.idx);
- } else {
- println!("not found");
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement