blob: 58d41cc8b2b6e895c5d871a7196e87925e6dc162 [file] [log] [blame]
#![cfg(rayon_unstable)]
use super::ThreadPool;
use internal::task::{ScopeHandle, Task, ToScopeHandle};
use registry::Registry;
use std::any::Any;
use std::fmt;
use std::sync::Arc;
impl ToScopeHandle<'static> for ThreadPool {
type ScopeHandle = ThreadPoolScopeHandle;
fn to_scope_handle(&self) -> Self::ScopeHandle {
unsafe { ThreadPoolScopeHandle::new(self.registry.clone()) }
}
}
pub struct ThreadPoolScopeHandle {
registry: Arc<Registry>,
}
impl fmt::Debug for ThreadPoolScopeHandle {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("ThreadPoolScopeHandle")
.field("pool", &self.registry.id())
.finish()
}
}
impl ThreadPoolScopeHandle {
/// Caller asserts that the registry has not yet terminated.
unsafe fn new(registry: Arc<Registry>) -> Self {
registry.increment_terminate_count();
ThreadPoolScopeHandle { registry: registry }
}
}
impl Drop for ThreadPoolScopeHandle {
fn drop(&mut self) {
self.registry.terminate();
}
}
/// We assert that:
///
/// (a) the scope valid remains valid until a completion method
/// is called. In this case, "remains valid" means that the
/// registry is not terminated. This is true because we
/// acquire a "termination count" in `StaticFutureScope::new()`
/// which is not released until `future_panicked()` or
/// `future_completed()` is invoked.
/// (b) the lifetime `'static` will not end until a completion
/// method is called. This is true because `'static` doesn't
/// end until the end of the program.
unsafe impl ScopeHandle<'static> for ThreadPoolScopeHandle {
unsafe fn spawn_task<T: Task + 'static>(&self, task: Arc<T>) {
self.registry.submit_task(task);
}
fn ok(self) {}
fn panicked(self, err: Box<Any + Send>) {
self.registry.handle_panic(err);
}
}