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}