diff options
Diffstat (limited to 'components/script/dom/globalscope.rs')
-rw-r--r-- | components/script/dom/globalscope.rs | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 433a24ae786..eec99116bcf 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -52,7 +52,9 @@ use crate::dom::workletglobalscope::WorkletGlobalScope; use crate::microtask::{Microtask, MicrotaskQueue, UserMicrotask}; use crate::realms::{enter_realm, AlreadyInRealm, InRealm}; use crate::script_module::ModuleTree; -use crate::script_runtime::{CommonScriptMsg, JSContext as SafeJSContext, ScriptChan, ScriptPort}; +use crate::script_runtime::{ + CommonScriptMsg, ContextForRequestInterrupt, JSContext as SafeJSContext, ScriptChan, ScriptPort, +}; use crate::script_thread::{MainThreadScriptChan, ScriptThread}; use crate::task::TaskCanceller; use crate::task_source::dom_manipulation::DOMManipulationTaskSource; @@ -130,6 +132,8 @@ pub struct AutoCloseWorker { /// A sender of control messages, /// currently only used to signal shutdown. control_sender: Sender<DedicatedWorkerControlMsg>, + /// The context to request an interrupt on the worker thread. + context: ContextForRequestInterrupt, } impl Drop for AutoCloseWorker { @@ -146,6 +150,8 @@ impl Drop for AutoCloseWorker { warn!("Couldn't send an exit message to a dedicated worker."); } + self.context.request_interrupt(); + // TODO: step 2 and 3. // Step 4 is unnecessary since we don't use actual ports for dedicated workers. if self @@ -2049,6 +2055,7 @@ impl GlobalScope { closing: Arc<AtomicBool>, join_handle: JoinHandle<()>, control_sender: Sender<DedicatedWorkerControlMsg>, + context: ContextForRequestInterrupt, ) { self.list_auto_close_worker .borrow_mut() @@ -2056,6 +2063,7 @@ impl GlobalScope { closing, join_handle: Some(join_handle), control_sender: control_sender, + context, }); } @@ -2713,6 +2721,20 @@ impl GlobalScope { unreachable!(); } + /// Returns a boolean indicating whether the event-loop + /// where this global is running on can continue running JS. + pub fn can_continue_running(&self) -> bool { + if self.downcast::<Window>().is_some() { + return ScriptThread::can_continue_running(); + } + if let Some(worker) = self.downcast::<WorkerGlobalScope>() { + return !worker.is_closing(); + } + + // TODO: plug worklets into this. + true + } + /// Returns the task canceller of this global to ensure that everything is /// properly cancelled when the global scope is destroyed. pub fn task_canceller(&self, name: TaskSourceName) -> TaskCanceller { @@ -2730,11 +2752,14 @@ impl GlobalScope { /// Perform a microtask checkpoint. pub fn perform_a_microtask_checkpoint(&self) { - self.microtask_queue.checkpoint( - self.get_cx(), - |_| Some(DomRoot::from_ref(self)), - vec![DomRoot::from_ref(self)], - ); + // Only perform the checkpoint if we're not shutting down. + if self.can_continue_running() { + self.microtask_queue.checkpoint( + self.get_cx(), + |_| Some(DomRoot::from_ref(self)), + vec![DomRoot::from_ref(self)], + ); + } } /// Enqueue a microtask for subsequent execution. @@ -2761,8 +2786,9 @@ impl GlobalScope { } /// Process a single event as if it were the next event - /// in the thread queue for this global scope. - pub fn process_event(&self, msg: CommonScriptMsg) { + /// in the queue for the event-loop where this global scope is running on. + /// Returns a boolean indicating whether further events should be processed. + pub fn process_event(&self, msg: CommonScriptMsg) -> bool { if self.is::<Window>() { return ScriptThread::process_event(msg); } |