use super::builder::Builder;
use super::pool::Pool;
use super::sender::Sender;
use super::shutdown::{Shutdown, ShutdownTrigger};
use std::future::Future;
use std::sync::Arc;
#[derive(Debug)]
pub struct ThreadPool {
inner: Option<Inner>,
}
#[derive(Debug)]
struct Inner {
sender: Sender,
trigger: Arc<ShutdownTrigger>,
}
impl ThreadPool {
pub fn new() -> ThreadPool {
Builder::new().build()
}
pub(crate) fn new2(pool: Arc<Pool>, trigger: Arc<ShutdownTrigger>) -> ThreadPool {
ThreadPool {
inner: Some(Inner {
sender: Sender { pool },
trigger,
}),
}
}
pub fn spawn<F>(&self, future: F)
where
F: Future<Output = ()> + Send + 'static,
{
self.sender().spawn(future).unwrap();
}
pub fn sender(&self) -> &Sender {
&self.inner.as_ref().unwrap().sender
}
pub fn sender_mut(&mut self) -> &mut Sender {
&mut self.inner.as_mut().unwrap().sender
}
pub fn shutdown_on_idle(mut self) -> Shutdown {
let inner = self.inner.take().unwrap();
inner.sender.pool.shutdown(false, false);
Shutdown::new(&inner.trigger)
}
pub fn shutdown(mut self) -> Shutdown {
let inner = self.inner.take().unwrap();
inner.sender.pool.shutdown(true, false);
Shutdown::new(&inner.trigger)
}
pub fn shutdown_now(mut self) -> Shutdown {
let inner = self.inner.take().unwrap();
inner.sender.pool.shutdown(true, true);
Shutdown::new(&inner.trigger)
}
}
impl Drop for ThreadPool {
fn drop(&mut self) {
if let Some(inner) = self.inner.take() {
inner.sender.pool.shutdown(true, true);
let shutdown = Shutdown::new(&inner.trigger);
drop(inner);
let mut enter = match crate::enter() {
Ok(e) => e,
Err(_) => return,
};
enter.block_on(shutdown);
}
}
}
impl Default for ThreadPool {
fn default() -> Self {
Self::new()
}
}