1use async_std::sync::{Condvar, Mutex};
2
3pub struct Pool<T> {
4 sync_tuple: Mutex<(Vec<T>, usize)>,
5 condvar: Condvar,
6 create_max: usize
7}
8
9impl<T> Pool<T> {
10 pub fn new(create_max: usize) -> Self {
11 Self {
12 sync_tuple: Mutex::new((Vec::new(), 0)),
13 condvar: Condvar::new(),
14 create_max,
15 }
16 }
17
18 pub async fn put(&self, item: T) {
19 let mut lock_guard = (&self.sync_tuple).lock().await;
20 (*lock_guard).0.push(item);
21 self.condvar.notify_one();
22 }
23
24 pub async fn take_or_create<F>(&self, creator_fn: F) -> T where
25 F: Fn() -> T {
26 let mut lock_guard = (&self.sync_tuple).lock().await;
27
28 while (*lock_guard).0.is_empty() && (*lock_guard).1 == self.create_max {
29 lock_guard = self.condvar.wait(lock_guard).await;
30 }
31
32 if (*lock_guard).1 < self.create_max {
33 (*lock_guard).0.push((creator_fn)());
34 (*lock_guard).1 += 1;
35 }
36
37 return (*lock_guard).0.remove(0);
38 }
39}
40
41
42#[cfg(test)]
43mod tests {
44 use async_std::task;
45 use crate::Pool;
46
47 #[test]
48 fn usage_example() -> std::io::Result<()> {
49 task::block_on(async {
50 let pool = Pool::new(100);
52
53 let item = pool.take_or_create(|| String::from("hello")).await;
57
58 println!("{}", item);
60
61 pool.put(item).await;
63 });
64 Ok(())
65 }
66}