diff options
Diffstat (limited to 'components/script/dom/worklet.rs')
-rw-r--r-- | components/script/dom/worklet.rs | 187 |
1 files changed, 117 insertions, 70 deletions
diff --git a/components/script/dom/worklet.rs b/components/script/dom/worklet.rs index 498cce10680..84a2b6f696b 100644 --- a/components/script/dom/worklet.rs +++ b/components/script/dom/worklet.rs @@ -92,7 +92,11 @@ impl Worklet { pub fn new(window: &Window, global_type: WorkletGlobalScopeType) -> DomRoot<Worklet> { debug!("Creating worklet {:?}.", global_type); - reflect_dom_object(Box::new(Worklet::new_inherited(window, global_type)), window, Wrap) + reflect_dom_object( + Box::new(Worklet::new_inherited(window, global_type)), + window, + Wrap, + ) } pub fn worklet_id(&self) -> WorkletId { @@ -120,7 +124,7 @@ impl WorkletMethods for Worklet { debug!("URL {:?} parse error {:?}.", module_url.0, err); promise.reject_error(Error::Syntax); return promise; - } + }, }; debug!("Adding Worklet module {}.", module_url_record); @@ -129,15 +133,17 @@ impl WorkletMethods for Worklet { let global = self.window.upcast::<GlobalScope>(); let pool = ScriptThread::worklet_thread_pool(); - pool.fetch_and_invoke_a_worklet_script(global.pipeline_id(), - self.worklet_id, - self.global_type, - self.window.origin().immutable().clone(), - global.api_base_url(), - module_url_record, - options.credentials.clone(), - pending_tasks_struct, - &promise); + pool.fetch_and_invoke_a_worklet_script( + global.pipeline_id(), + self.worklet_id, + self.global_type, + self.window.origin().immutable().clone(), + global.api_base_url(), + module_url_record, + options.credentials.clone(), + pending_tasks_struct, + &promise, + ); // Step 5. debug!("Returning promise."); @@ -163,7 +169,9 @@ struct PendingTasksStruct(Arc<AtomicIsize>); impl PendingTasksStruct { fn new() -> PendingTasksStruct { - PendingTasksStruct(Arc::new(AtomicIsize::new(WORKLET_THREAD_POOL_SIZE as isize))) + PendingTasksStruct(Arc::new(AtomicIsize::new( + WORKLET_THREAD_POOL_SIZE as isize, + ))) } fn set_counter_to(&self, value: isize) -> isize { @@ -274,19 +282,24 @@ impl WorkletThreadPool { /// 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> - 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>) - { + 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>, + ) { // Send each thread a control message asking it to load the script. - for sender in &[&self.control_sender_0, &self.control_sender_1, &self.control_sender_2] { + for sender in &[ + &self.control_sender_0, + &self.control_sender_1, + &self.control_sender_2, + ] { let _ = sender.send(WorkletControl::FetchAndInvokeAWorkletScript { pipeline_id: pipeline_id, worklet_id: worklet_id, @@ -454,7 +467,7 @@ impl WorkletThread { // The whole point of this thread pool is to perform tasks! WorkletData::Task(id, task) => { self.perform_a_worklet_task(id, task); - } + }, // To start swapping roles, get ready to perform an atomic swap, // and block waiting for the other end to finish it. // NOTE: the cold backup can block on the primary or the hot backup; @@ -463,21 +476,22 @@ impl WorkletThread { // this total ordering on thread roles is what guarantees deadlock-freedom. WorkletData::StartSwapRoles(sender) => { let (our_swapper, their_swapper) = swapper(); - sender.send(WorkletData::FinishSwapRoles(their_swapper)).unwrap(); + sender + .send(WorkletData::FinishSwapRoles(their_swapper)) + .unwrap(); let _ = our_swapper.swap(&mut self.role); - } + }, // To finish swapping roles, perform the atomic swap. // The other end should have already started the swap, so this shouldn't block. WorkletData::FinishSwapRoles(swapper) => { let _ = swapper.swap(&mut self.role); - } + }, // Wake up! There may be control messages to process. - WorkletData::WakeUp => { - } + WorkletData::WakeUp => {}, // Quit! WorkletData::Quit => { return; - } + }, } // Only process control messages if we're the cold backup, // otherwise if there are outstanding control messages, @@ -522,27 +536,41 @@ impl WorkletThread { /// Perform a GC. #[allow(unsafe_code)] fn gc(&mut self) { - debug!("BEGIN GC (usage = {}, threshold = {}).", self.current_memory_usage(), self.gc_threshold); + debug!( + "BEGIN GC (usage = {}, threshold = {}).", + self.current_memory_usage(), + self.gc_threshold + ); unsafe { JS_GC(self.runtime.cx()) }; self.gc_threshold = max(MIN_GC_THRESHOLD, self.current_memory_usage() * 2); - debug!("END GC (usage = {}, threshold = {}).", self.current_memory_usage(), self.gc_threshold); + debug!( + "END GC (usage = {}, threshold = {}).", + self.current_memory_usage(), + self.gc_threshold + ); } /// Get the worklet global scope for a given worklet. /// Creates the worklet global scope if it doesn't exist. - fn get_worklet_global_scope(&mut self, - pipeline_id: PipelineId, - worklet_id: WorkletId, - global_type: WorkletGlobalScopeType, - base_url: ServoUrl) - -> DomRoot<WorkletGlobalScope> - { + fn get_worklet_global_scope( + &mut self, + pipeline_id: PipelineId, + worklet_id: WorkletId, + global_type: WorkletGlobalScopeType, + base_url: ServoUrl, + ) -> DomRoot<WorkletGlobalScope> { match self.global_scopes.entry(worklet_id) { hash_map::Entry::Occupied(entry) => DomRoot::from_ref(entry.get()), hash_map::Entry::Vacant(entry) => { debug!("Creating new worklet global scope."); let executor = WorkletExecutor::new(worklet_id, self.primary_sender.clone()); - let result = global_type.new(&self.runtime, pipeline_id, base_url, executor, &self.global_init); + let result = global_type.new( + &self.runtime, + pipeline_id, + base_url, + executor, + &self.global_init, + ); entry.insert(Dom::from_ref(&*result)); result }, @@ -551,15 +579,16 @@ impl WorkletThread { /// Fetch and invoke a worklet script. /// <https://drafts.css-houdini.org/worklets/#fetch-and-invoke-a-worklet-script> - fn fetch_and_invoke_a_worklet_script(&self, - global_scope: &WorkletGlobalScope, - pipeline_id: PipelineId, - origin: ImmutableOrigin, - script_url: ServoUrl, - credentials: RequestCredentials, - pending_tasks_struct: PendingTasksStruct, - promise: TrustedPromise) - { + fn fetch_and_invoke_a_worklet_script( + &self, + global_scope: &WorkletGlobalScope, + pipeline_id: PipelineId, + origin: ImmutableOrigin, + script_url: ServoUrl, + credentials: RequestCredentials, + pending_tasks_struct: PendingTasksStruct, + promise: TrustedPromise, + ) { debug!("Fetching from {}.", script_url); // Step 1. // TODO: Settings object? @@ -575,9 +604,10 @@ impl WorkletThread { mode: RequestMode::CorsMode, credentials_mode: credentials.into(), origin, - .. RequestInit::default() + ..RequestInit::default() }; - let script = load_whole_resource(request, &resource_fetcher).ok() + let script = load_whole_resource(request, &resource_fetcher) + .ok() .and_then(|(_, bytes)| String::from_utf8(bytes).ok()); // Step 4. @@ -586,7 +616,9 @@ impl WorkletThread { // Also, the spec currently doesn't allow exceptions to be propagated // to the main script thread. // https://github.com/w3c/css-houdini-drafts/issues/407 - let ok = script.map(|script| global_scope.evaluate_js(&*script)).unwrap_or(false); + let ok = script + .map(|script| global_scope.evaluate_js(&*script)) + .unwrap_or(false); if !ok { // Step 3. @@ -602,7 +634,10 @@ impl WorkletThread { if old_counter == 1 { debug!("Resolving promise."); let msg = MainThreadScriptMsg::WorkletLoaded(pipeline_id); - self.global_init.to_script_thread_sender.send(msg).expect("Worklet thread outlived script thread."); + self.global_init + .to_script_thread_sender + .send(msg) + .expect("Worklet thread outlived script thread."); self.run_in_script_thread(promise.resolve_task(())); } } @@ -620,21 +655,28 @@ impl WorkletThread { fn process_control(&mut self, control: WorkletControl) { match control { WorkletControl::FetchAndInvokeAWorkletScript { - pipeline_id, worklet_id, global_type, origin, base_url, - script_url, credentials, pending_tasks_struct, promise, + pipeline_id, + worklet_id, + global_type, + origin, + base_url, + script_url, + credentials, + pending_tasks_struct, + promise, } => { - let global = self.get_worklet_global_scope(pipeline_id, - worklet_id, - global_type, - base_url); - self.fetch_and_invoke_a_worklet_script(&*global, - pipeline_id, - origin, - script_url, - credentials, - pending_tasks_struct, - promise) - } + let global = + self.get_worklet_global_scope(pipeline_id, worklet_id, global_type, base_url); + self.fetch_and_invoke_a_worklet_script( + &*global, + pipeline_id, + origin, + script_url, + credentials, + pending_tasks_struct, + promise, + ) + }, } } @@ -652,7 +694,10 @@ impl WorkletThread { TaskSourceName::DOMManipulation, ); let msg = MainThreadScriptMsg::Common(msg); - self.global_init.to_script_thread_sender.send(msg).expect("Worklet thread outlived script thread."); + self.global_init + .to_script_thread_sender + .send(msg) + .expect("Worklet thread outlived script thread."); } } @@ -674,6 +719,8 @@ impl WorkletExecutor { /// Schedule a worklet task to be peformed by the worklet thread pool. pub fn schedule_a_worklet_task(&self, task: WorkletTask) { - let _ = self.primary_sender.send(WorkletData::Task(self.worklet_id, task)); + let _ = self + .primary_sender + .send(WorkletData::Task(self.worklet_id, task)); } } |