use crate::NumThreads;
use crate::pools::scope::Scope;
use crate::pools::{ThreadPool, env::max_num_threads_by_env_and_resource};
use core::num::NonZeroUsize;
#[derive(Clone, Copy, Debug)]
pub struct OncePool {
num_threads: NonZeroUsize,
}
impl Default for OncePool {
fn default() -> Self {
Self::new(NumThreads::Auto)
}
}
unsafe impl Sync for OncePool {}
impl OncePool {
pub fn new(num_threads: impl Into<NumThreads>) -> Self {
let num_threads = match num_threads.into() {
NumThreads::Auto => max_num_threads_by_env_and_resource(),
NumThreads::Max(n) => max_num_threads_by_env_and_resource().min(n),
};
Self { num_threads }
}
}
impl<'s, 'env, 'scope> Scope<'s, 'env, 'scope> for &'s std::thread::Scope<'s, 'env> {
fn run<W>(self, work: W)
where
'scope: 's,
'env: 'scope + 's,
W: FnOnce() + Send + 'scope + 'env,
{
self.spawn(work);
}
}
impl ThreadPool for OncePool {
type ScopeRef<'s, 'env, 'scope>
= &'s std::thread::Scope<'s, 'env>
where
'scope: 's,
'env: 'scope + 's;
fn max_num_threads(&self) -> NonZeroUsize {
self.num_threads
}
fn scope<'env, 'scope, F>(&'env self, f: F)
where
'env: 'scope,
for<'s> F: FnOnce(&'s std::thread::Scope<'s, 'env>) + Send,
{
std::thread::scope(f)
}
}
impl ThreadPool for &OncePool {
type ScopeRef<'s, 'env, 'scope>
= &'s std::thread::Scope<'s, 'env>
where
'scope: 's,
'env: 'scope + 's;
fn max_num_threads(&self) -> NonZeroUsize {
self.num_threads
}
fn scope<'env, 'scope, F>(&'env self, f: F)
where
'env: 'scope,
for<'s> F: FnOnce(&'s std::thread::Scope<'s, 'env>) + Send,
{
std::thread::scope(f)
}
}
impl ThreadPool for &mut OncePool {
type ScopeRef<'s, 'env, 'scope>
= &'s std::thread::Scope<'s, 'env>
where
'scope: 's,
'env: 'scope + 's;
fn max_num_threads(&self) -> NonZeroUsize {
self.num_threads
}
fn scope<'env, 'scope, F>(&'env self, f: F)
where
'env: 'scope,
for<'s> F: FnOnce(&'s std::thread::Scope<'s, 'env>) + Send,
{
std::thread::scope(f)
}
}