use core::marker::PhantomData;
use core::mem;
use crate::worker::Job;
use crate::{Counter, ThreadPool};
pub struct Scope<'scope, 'pool: 'scope> {
scope_counter: Counter,
pool: &'pool ThreadPool,
_marker_scope: PhantomData<&'scope mut &'scope ()>,
}
impl<'scope, 'pool> Scope<'scope, 'pool> {
pub(super) fn new(pool: &'pool ThreadPool) -> Self {
Self {
scope_counter: Counter::new(),
pool,
_marker_scope: PhantomData,
}
}
pub fn execute(&self, job: impl Job<'scope>) {
let job: Box<dyn Job<'scope>> = Box::new(job);
let job: Box<dyn Job<'static>> = unsafe { mem::transmute(job) };
self.pool.execute_inside_scope(job, self.scope_counter.clone());
}
pub fn subscope<'new, F, R>(&self, f: F) -> R
where
F: FnOnce(&Scope<'new, 'pool>) -> R,
'scope: 'new
{
let scope = Scope {
scope_counter: Counter::new(),
pool: self.pool,
_marker_scope: PhantomData,
};
f(&scope)
}
}
impl Drop for Scope<'_, '_> {
fn drop(&mut self) {
self.scope_counter.join();
}
}