Struct script::dom::worklet::WorkletThreadPool
source · pub struct WorkletThreadPool {
primary_sender: Sender<WorkletData>,
hot_backup_sender: Sender<WorkletData>,
cold_backup_sender: Sender<WorkletData>,
control_sender_0: Sender<WorkletControl>,
control_sender_1: Sender<WorkletControl>,
control_sender_2: Sender<WorkletControl>,
}
Expand description
Worklets execute in a dedicated thread pool.
The goal is to ensure that there is a primary worklet thread, which is able to responsively execute worklet code. In particular, worklet execution should not be delayed by GC, or by script loading.
To achieve this, we implement a three-thread pool, with the threads cycling between three thread roles:
-
The primary worklet thread is the one available to execute worklet code.
-
The hot backup thread may peform GC, but otherwise is expected to take over the primary role.
-
The cold backup thread may peform script loading and other long-running tasks.
In the implementation, we use two kinds of messages:
-
Data messages are expected to be processed quickly, and include the worklet tasks to be performed by the primary thread, as well as requests to change role or quit execution.
-
Control messages are expected to be processed more slowly, and include script loading.
Data messages are targeted at a role, for example, task execution is expected to be performed by whichever thread is currently primary. Control messages are targeted at a thread, for example adding a module is performed in every thread, even if they change roles in the middle of module loading.
The thread pool lives in the script thread, and is initialized when a worklet adds a module. It is dropped when the script thread is dropped, and asks each of the worklet threads to quit.
Layout can end up blocking on the primary worklet thread (e.g. when invoking a paint callback), so it is important to avoid deadlock by making sure the primary worklet thread doesn’t end up blocking waiting on layout. In particular, since the constellation can block waiting on layout, this means the primary worklet thread can’t block waiting on the constellation. In general, the primary worklet thread shouldn’t perform any blocking operations. If a worklet thread needs to do anything blocking, it should send a control message, to make sure that the blocking operation is performed by a backup thread, not by the primary thread.
Fields§
§primary_sender: Sender<WorkletData>
§hot_backup_sender: Sender<WorkletData>
§cold_backup_sender: Sender<WorkletData>
§control_sender_0: Sender<WorkletControl>
§control_sender_1: Sender<WorkletControl>
§control_sender_2: Sender<WorkletControl>
Implementations§
source§impl WorkletThreadPool
impl WorkletThreadPool
sourcepub fn spawn(global_init: WorkletGlobalScopeInit) -> WorkletThreadPool
pub fn spawn(global_init: WorkletGlobalScopeInit) -> WorkletThreadPool
Create a new thread pool and spawn the threads. When the thread pool is dropped, the threads will be asked to quit.
sourcefn fetch_and_invoke_a_worklet_script(
&self,
pipeline_id: PipelineId,
worklet_id: WorkletId,
global_type: WorkletGlobalScopeType,
origin: ImmutableOrigin,
base_url: ServoUrl,
script_url: ServoUrl,
credentials: RequestCredentials,
pending_tasks_struct: PendingTasksStruct,
promise: &Rc<Promise>,
)
fn fetch_and_invoke_a_worklet_script( &self, pipeline_id: PipelineId, worklet_id: WorkletId, global_type: WorkletGlobalScopeType, origin: ImmutableOrigin, base_url: ServoUrl, script_url: ServoUrl, credentials: RequestCredentials, pending_tasks_struct: PendingTasksStruct, promise: &Rc<Promise>, )
Loads a worklet module into every worklet thread. If all of the threads load successfully, the promise is resolved. If any of the threads fails to load, the promise is rejected. https://drafts.css-houdini.org/worklets/#fetch-and-invoke-a-worklet-script
pub(crate) fn exit_worklet(&self, worklet_id: WorkletId)
fn wake_threads(&self)
Trait Implementations§
source§impl Clone for WorkletThreadPool
impl Clone for WorkletThreadPool
source§fn clone(&self) -> WorkletThreadPool
fn clone(&self) -> WorkletThreadPool
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl Drop for WorkletThreadPool
impl Drop for WorkletThreadPool
Auto Trait Implementations§
impl Freeze for WorkletThreadPool
impl RefUnwindSafe for WorkletThreadPool
impl Send for WorkletThreadPool
impl Sync for WorkletThreadPool
impl Unpin for WorkletThreadPool
impl UnwindSafe for WorkletThreadPool
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)source§impl<T> Filterable for T
impl<T> Filterable for T
source§fn filterable(
self,
filter_name: &'static str,
) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>
fn filterable( self, filter_name: &'static str, ) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more