use std::thread;
use super::fixed_thread_pool::FixedThreadPool;
use super::thread_pool::ThreadPoolBuildError;
const DEFAULT_FIXED_THREAD_NAME_PREFIX: &str = "qubit-fixed-thread-pool";
#[derive(Debug, Clone)]
pub struct FixedThreadPoolBuilder {
pool_size: usize,
queue_capacity: Option<usize>,
thread_name_prefix: String,
stack_size: Option<usize>,
}
impl FixedThreadPoolBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn pool_size(mut self, pool_size: usize) -> Self {
self.pool_size = pool_size;
self
}
pub fn queue_capacity(mut self, capacity: usize) -> Self {
self.queue_capacity = Some(capacity);
self
}
pub fn unbounded_queue(mut self) -> Self {
self.queue_capacity = None;
self
}
pub fn thread_name_prefix(mut self, prefix: &str) -> Self {
self.thread_name_prefix = prefix.to_owned();
self
}
pub fn stack_size(mut self, stack_size: usize) -> Self {
self.stack_size = Some(stack_size);
self
}
pub fn build(self) -> Result<FixedThreadPool, ThreadPoolBuildError> {
self.validate()?;
FixedThreadPool::build_with_options(
self.pool_size,
self.queue_capacity,
self.thread_name_prefix,
self.stack_size,
)
}
fn validate(&self) -> Result<(), ThreadPoolBuildError> {
if self.pool_size == 0 {
return Err(ThreadPoolBuildError::ZeroMaximumPoolSize);
}
if self.queue_capacity == Some(0) {
return Err(ThreadPoolBuildError::ZeroQueueCapacity);
}
if self.stack_size == Some(0) {
return Err(ThreadPoolBuildError::ZeroStackSize);
}
Ok(())
}
}
impl Default for FixedThreadPoolBuilder {
fn default() -> Self {
Self {
pool_size: default_fixed_pool_size(),
queue_capacity: None,
thread_name_prefix: DEFAULT_FIXED_THREAD_NAME_PREFIX.to_owned(),
stack_size: None,
}
}
}
fn default_fixed_pool_size() -> usize {
thread::available_parallelism()
.map(usize::from)
.unwrap_or(1)
}