use crate::park::Unpark; use crate::task::{self, Schedule, Task}; use crate::thread_pool::worker; use std::ptr; /// Per-worker data accessible from any thread. /// /// Accessed by: /// /// - other workers /// - tasks /// pub(crate) struct Shared

where P: 'static, { /// Thread unparker unpark: P, /// Tasks pending drop. Any worker pushes tasks, only the "owning" worker /// pops. pub(super) pending_drop: task::TransferStack, /// Untracked pointer to the pool. /// /// The pool itself is tracked by an `Arc`, but this pointer is not included /// in the ref count. /// /// # Safety /// /// `Worker` instances are stored in the `Pool` and are never removed. set: *const worker::Set

, } unsafe impl Send for Shared

{} unsafe impl Sync for Shared

{} impl

Shared

where P: Unpark, { pub(super) fn new(unpark: P) -> Shared

{ Shared { unpark, pending_drop: task::TransferStack::new(), set: ptr::null(), } } pub(crate) fn schedule(&self, task: Task) { self.set().schedule(task); } pub(super) fn unpark(&self) { self.unpark.unpark(); } pub(super) fn set_container_ptr(&mut self, set: *const worker::Set

) { self.set = set; } fn set(&self) -> &worker::Set

{ unsafe { &*self.set } } } impl

Schedule for Shared

where P: Unpark, { fn bind(&self, task: &Task) { // Get access to the Owned component. This function can only be called // when on the worker. unsafe { let index = self.set().index_of(self); let owned = &mut *self.set().owned()[index].get(); owned.bind_task(task); } } fn release(&self, task: Task) { // This stores the task with the owning worker. The worker is not // notified. Instead, the worker will clean up the tasks "eventually". // self.pending_drop.push(task); } fn release_local(&self, task: &Task) { // Get access to the Owned component. This function can only be called // when on the worker. unsafe { let index = self.set().index_of(self); let owned = &mut *self.set().owned()[index].get(); owned.release_task(task); } } fn schedule(&self, task: Task) { Self::schedule(self, task); } }