1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//! ## Worker Pool
//!
//! This module contains constructs for dealing with concurrent tasks. It can spawn
//! any number of worker threads and sync them with other channels.
//!
//! ## Examples
//!
//! ### Synchronized with other channels
//!
//! ```
//! use workerpool_rs::pool::WorkerPool;
//! use std::sync::mpsc::channel;
//! use std::sync::{Arc, Mutex};
//!
//! let n_workers = 4;
//! let n_jobs = 8;
//! let pool = WorkerPool::new(n_workers);
//!
//! let (tx, rx) = channel();
//! let atx = Arc::new(Mutex::new(tx));
//! for _ in 0..n_jobs {
//!     let atx = atx.clone();
//!     pool.execute(move|| {
//!         let tx = atx.lock().unwrap();
//!         tx.send(1).expect("channel will be there waiting for the pool");
//!     });
//! }
//!
//! assert_eq!(rx.iter().take(n_jobs).fold(0, |a, b| a + b), 8);
//!```
//!
//! ### Sinchronized with Barrier
//!```
//!
//! use std::sync::atomic::{AtomicUsize, Ordering};
//! use std::sync::{Arc, Barrier};
//! use workerpool_rs::pool::WorkerPool;
//!
//! let n_workers = 42;
//! let n_jobs = 23;
//! let pool = WorkerPool::new(n_workers);
//! let an_atomic = Arc::new(AtomicUsize::new(0));
//!
//! assert!(n_jobs <= n_workers, "too many jobs, will deadlock");
//!
//! let barrier = Arc::new(Barrier::new(n_jobs + 1));
//! for _ in 0..n_jobs {
//!     let barrier = barrier.clone();
//!     let an_atomic = an_atomic.clone();
//!
//!     pool.execute(move|| {
//!         // do the heavy work
//!         an_atomic.fetch_add(1, Ordering::Relaxed);
//!
//!         // then wait for the other threads
//!         barrier.wait();
//!     });
//! }
//!
//! barrier.wait();
//! assert_eq!(an_atomic.load(Ordering::SeqCst), /* n_jobs = */ 23);
//!```

// Imports and makes pool public.
pub mod pool;