job_pool/
lib.rs

1/*  Copyright (C) 2025 Saúl Valdelvira
2 *
3 *  This program is free software: you can redistribute it and/or modify
4 *  it under the terms of the GNU General Public License as published by
5 *  the Free Software Foundation, version 3.
6 *
7 *  This program is distributed in the hope that it will be useful,
8 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *  GNU General Public License for more details.
11 *
12 *  You should have received a copy of the GNU General Public License
13 *  along with this program.  If not, see <https://www.gnu.org/licenses/>. */
14
15//! Thread Pool
16//!
17//! This crate contains code to run a Job pool.
18//!
19//! # Example
20//! ```rust,no_run
21//! use job_pool::*;
22//! use std::thread;
23//! use std::time::Duration;
24//!
25//! let conf = PoolConfig::default();
26//! let pool = ThreadPool::new(conf).unwrap();
27//! for _ in 0..10 {
28//!     pool.execute(|| {
29//!         thread::sleep(Duration::from_secs(5));
30//!     });
31//! }
32//! pool.join();
33//! ```
34
35#![cfg_attr(feature = "use-nightly-mpmc", feature(mpmc_channel))]
36
37#[cfg(feature = "bindings")]
38mod ffi;
39
40mod pool;
41mod worker;
42mod config;
43mod scope;
44pub use scope::Scope;
45
46/* Switch between mpsc and mpmc until
47 * std::sync::mpmc is stabilized */
48
49#[cfg(feature = "use-nightly-mpmc")]
50#[path ="channel/mpmc.rs"]
51mod channel;
52
53#[cfg(not(feature = "use-nightly-mpmc"))]
54#[path ="channel/mpsc.rs"]
55mod channel;
56
57use std::borrow::Cow;
58use std::sync::{Arc, Condvar, Mutex};
59
60pub use pool::ThreadPool;
61pub use config::PoolConfig;
62
63pub type Result<T> = std::result::Result<T,Cow<'static,str>>;
64
65#[derive(Clone)]
66struct Counter(Arc<(Mutex<u16>,Condvar)>);
67
68impl Counter {
69    pub fn new() -> Self {
70        Self(Arc::new((Mutex::new(0), Condvar::new())))
71    }
72
73    pub fn inc(&self, max: Option<u16>) {
74        let (lock,cvar) = &*self.0;
75        let mut counter = lock.lock().unwrap();
76        if let Some(max) = max {
77            counter = cvar.wait_while(counter, |n| *n >= max).unwrap();
78        }
79        *counter += 1;
80
81    }
82
83    pub fn count(&self) -> u16 {
84        *self.0.0.lock().unwrap()
85    }
86
87    pub fn dec(&self) {
88        let (lock,condv) = &*self.0;
89        let mut counter = lock.lock().unwrap();
90        *counter -= 1;
91        condv.notify_one();
92    }
93
94    pub fn join(&self) {
95        let (lock,cvar) = &*self.0;
96        let counter = lock.lock().unwrap();
97        let _lock = cvar.wait_while(counter, |n| *n > 0).unwrap();
98    }
99}