Script: ensure child JS runtimes are dropped before parent (#30896)

* clear js runtime of dedicated worker that immediately exits

* dedicated worker: clear js runtime if loading script fails

* when the script thread crashes, deallocate worker runtimes before dropping main runtime

* clear runtime if service worker script fails to load

* ensure worker enter their realm before executing script
This commit is contained in:
Gregory Terzian 2024-01-04 17:47:41 +08:00 committed by GitHub
parent 2f6f03a3b5
commit 90a9300f69
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 13 additions and 4 deletions

View file

@ -443,6 +443,7 @@ impl DedicatedWorkerGlobalScope {
TaskSourceName::DOMManipulation,
))
.unwrap();
scope.clear_js_runtime(context_for_interrupt);
return;
},
Ok((metadata, bytes)) => (metadata, bytes),
@ -457,11 +458,13 @@ impl DedicatedWorkerGlobalScope {
}
if scope.is_closing() {
scope.clear_js_runtime(context_for_interrupt);
return;
}
{
let _ar = AutoWorkerReset::new(&global, worker.clone());
let _ac = enter_realm(&*scope);
scope.execute_script(DOMString::from(source));
}

View file

@ -349,6 +349,8 @@ impl ServiceWorkerGlobalScope {
closing,
);
let scope = global.upcast::<WorkerGlobalScope>();
let referrer = referrer_url
.map(|url| Referrer::ReferrerUrl(url))
.unwrap_or_else(|| global.upcast::<GlobalScope>().get_referrer());
@ -367,6 +369,7 @@ impl ServiceWorkerGlobalScope {
{
Err(_) => {
println!("error loading script {}", serialized_worker_url);
scope.clear_js_runtime(context_for_interrupt);
return;
},
Ok((metadata, bytes)) => {
@ -374,15 +377,16 @@ impl ServiceWorkerGlobalScope {
},
};
let scope = global.upcast::<WorkerGlobalScope>();
let _ac = enter_realm(&*scope);
unsafe {
// Handle interrupt requests
JS_AddInterruptCallback(*scope.get_cx(), Some(interrupt_callback));
}
scope.execute_script(DOMString::from(source));
{
// TODO: use AutoWorkerReset as in dedicated worker?
let _ac = enter_realm(&*scope);
scope.execute_script(DOMString::from(source));
}
global.dispatch_activate();
let reporter_name = format!("service-worker-reporter-{}", random::<u64>());

View file

@ -393,6 +393,8 @@ impl Window {
#[allow(unsafe_code)]
pub fn clear_js_runtime_for_script_deallocation(&self) {
self.upcast::<GlobalScope>()
.remove_web_messaging_and_dedicated_workers_infra();
unsafe {
*self.js_runtime.borrow_for_script_deallocation() = None;
self.window_proxy.set(None);