Skip to main content

StatelessWorkletThreadPool

Struct StatelessWorkletThreadPool 

Source
pub(crate) struct StatelessWorkletThreadPool {
    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

The StatelessWorkletThreadPool executes the associated WorkletTasks in a dedicated thread pool with the assumption that the tasks are idempotent. This is useful for the paint worklet, for example.

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 StatelessWorkletThreadPool

Source

pub(crate) fn spawn( global_init: WorkletGlobalScopeInit, ) -> StatelessWorkletThreadPool

Create a new thread pool and spawn the threads. When the thread pool is dropped, the threads will be asked to quit.

Trait Implementations§

Source§

impl Clone for StatelessWorkletThreadPool

Source§

fn clone(&self) -> StatelessWorkletThreadPool

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Drop for StatelessWorkletThreadPool

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl Traceable for StatelessWorkletThreadPool

Source§

unsafe fn trace(&self, tracer: *mut JSTracer)

Trace self.
Source§

impl WorkletThreadPool for StatelessWorkletThreadPool

Source§

fn perform_a_worklet_task( &self, worklet_id: WorkletId, worklet_task: Box<dyn FnOnce(&mut JSContext, &WorkletGlobalScope) + Send>, )

Queue the WorkletTask for execution on the primary thread.

Source§

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, policy_container: PolicyContainer, credentials: RequestCredentials, pending_tasks_struct: PendingTasksStruct, promise: &Rc<Promise>, inherited_secure_context: Option<bool>, )

Loads a worklet module into every thread in this thread pool. If all of the threads load successfully, the promise is resolved. If any of the threads fails to load, the promise is rejected. NOTE: The method implements the Step 6 of AddModule https://html.spec.whatwg.org/multipage/#dom-worklet-addmodule
Source§

fn exit_worklet(&self, worklet_id: WorkletId)

Request that the WorkletGlobalScope associated with the WorkletId be removed from all the threads in the thread pool.
Source§

fn wake_threads(&self)

Signal all the threads in the pool that there may be control messages to process.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> MaybeBoxed<Box<T>> for T

Source§

fn maybe_boxed(self) -> Box<T>

Convert
Source§

impl<T> MaybeBoxed<T> for T

Source§

fn maybe_boxed(self) -> T

Convert
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, S> SimdFrom<T, S> for T
where S: Simd,

Source§

fn simd_from(_simd: S, value: T) -> T

Source§

impl<F, T, S> SimdInto<T, S> for F
where T: SimdFrom<F, S>, S: Simd,

Source§

fn simd_into(self, simd: S) -> T

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> MaybeSendSync for T

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,