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

source

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.

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, 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

source

pub(crate) fn exit_worklet(&self, worklet_id: WorkletId)

source

pub fn test_worklet_lookup(&self, id: WorkletId, key: String) -> Option<String>

For testing.

source

fn wake_threads(&self)

Trait Implementations§

source§

impl Clone for WorkletThreadPool

source§

fn clone(&self) -> WorkletThreadPool

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl Drop for WorkletThreadPool

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl Traceable for WorkletThreadPool

source§

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

Trace self.

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
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 Twhere 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, Global>> for T

source§

fn maybe_boxed(self) -> Box<T, Global>

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.
§

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<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere T: Clone,

§

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 Twhere U: Into<T>,

§

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 Twhere U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere V: MultiLane<T>,

source§

fn vzip(self) -> V

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<T> Erased for T

source§

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

source§

impl<T> MaybeSendSync for T

source§

impl<T> WasmNotSend for Twhere T: Send,

source§

impl<T> WasmNotSync for Twhere T: Sync,