Advertisement
Guest User

Untitled

a guest
May 19th, 2019
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.33 KB | None | 0 0
  1. use std::sync::{Arc, Mutex};
  2.  
  3. struct S {
  4. val: Option<usize>,
  5. }
  6.  
  7. struct LockedS {
  8. val: Arc<Mutex<S>>,
  9. idx: usize,
  10. }
  11.  
  12. struct Pool {
  13. inner: Mutex<Inner>,
  14. }
  15.  
  16. struct Inner {
  17. values: Vec<Arc<Mutex<S>>>,
  18. available: Vec<usize>,
  19. }
  20.  
  21. impl Pool {
  22. fn new() -> Self {
  23. let inner = Mutex::new(Inner {
  24. values: vec![],
  25. available: vec![],
  26. });
  27. Self {inner}
  28. }
  29.  
  30. fn acquire(&self) -> LockedS {
  31. let mut guard = self.inner.lock().unwrap();
  32. if let Some(idx) = guard.available.pop() {
  33. LockedS {
  34. val: Arc::clone(&guard.values[idx]),
  35. idx,
  36. }
  37. } else {
  38. let v = Arc::new(Mutex::new(S{val: None}));
  39. guard.values.push(Arc::clone(&v));
  40. LockedS {
  41. val: v,
  42. idx: guard.values.len() - 1,
  43. }
  44. }
  45. }
  46.  
  47. fn release(&self, s: LockedS) {
  48. let mut guard = self.inner.lock().unwrap();
  49. assert!(s.idx < guard.values.len());
  50. guard.available.push(s.idx);
  51. }
  52.  
  53. fn count(&self) -> usize {
  54. let guard = self.inner.lock().unwrap();
  55. guard.values.len()
  56. }
  57.  
  58. fn get_s(&self, idx: usize) -> Arc<Mutex<S>> {
  59. let guard = self.inner.lock().unwrap();
  60. Arc::clone(&guard.values[idx])
  61. }
  62.  
  63. fn find_valid_s(&self) -> Option<LockedS> {
  64. let mut idx = usize::max_value();
  65.  
  66. for i in 0..self.count() {
  67. let s = self.get_s(i);
  68. {
  69. if let Ok(guard) = s.try_lock() {
  70. if guard.val.is_some() {
  71. idx = i;
  72. break;
  73. }
  74. }
  75. }
  76. }
  77.  
  78. if idx != usize::max_value() {
  79. Some(LockedS{
  80. val: self.get_s(idx),
  81. idx,
  82. })
  83. } else {
  84. None
  85. }
  86. }
  87. }
  88.  
  89. fn main() {
  90. let pool = Pool::new();
  91. let ctrl = Ctrl {pool_ref: &pool};
  92.  
  93. {
  94. let _s = pool.acquire();
  95. }
  96. {
  97. let s = pool.acquire();
  98. let mut g = s.val.lock().unwrap();
  99. g.val = Some(0);
  100. }
  101.  
  102. if let Some(valid_s) = pool.find_valid_s() {
  103. println!("find valid with index: {}", valid_s.idx);
  104. } else {
  105. println!("not found");
  106. }
  107. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement