mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
add mechanism to join on service- and dedicated-worker threads
This commit is contained in:
parent
d7d56454b0
commit
ed688fe2c1
6 changed files with 63 additions and 18 deletions
|
@ -135,6 +135,7 @@ use std::path::PathBuf;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::atomic::{AtomicBool, AtomicUsize};
|
use std::sync::atomic::{AtomicBool, AtomicUsize};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use std::thread::JoinHandle;
|
||||||
use std::time::{Instant, SystemTime};
|
use std::time::{Instant, SystemTime};
|
||||||
use style::animation::ElementAnimationSet;
|
use style::animation::ElementAnimationSet;
|
||||||
use style::attr::{AttrIdentifier, AttrValue, LengthOrPercentageOrAuto};
|
use style::attr::{AttrIdentifier, AttrValue, LengthOrPercentageOrAuto};
|
||||||
|
@ -167,6 +168,7 @@ use webxr_api::SwapChainId as WebXRSwapChainId;
|
||||||
use webxr_api::{Finger, Hand, Ray, View};
|
use webxr_api::{Finger, Hand, Ray, View};
|
||||||
|
|
||||||
unsafe_no_jsmanaged_fields!(Tm);
|
unsafe_no_jsmanaged_fields!(Tm);
|
||||||
|
unsafe_no_jsmanaged_fields!(JoinHandle<()>);
|
||||||
|
|
||||||
/// A trait to allow tracing (only) DOM objects.
|
/// A trait to allow tracing (only) DOM objects.
|
||||||
pub unsafe trait JSTraceable {
|
pub unsafe trait JSTraceable {
|
||||||
|
|
|
@ -56,7 +56,7 @@ use servo_url::ServoUrl;
|
||||||
use std::mem::replace;
|
use std::mem::replace;
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::thread;
|
use std::thread::{self, JoinHandle};
|
||||||
use style::thread_state::{self, ThreadState};
|
use style::thread_state::{self, ThreadState};
|
||||||
|
|
||||||
/// Set the `worker` field of a related DedicatedWorkerGlobalScope object to a particular
|
/// Set the `worker` field of a related DedicatedWorkerGlobalScope object to a particular
|
||||||
|
@ -299,7 +299,7 @@ impl DedicatedWorkerGlobalScope {
|
||||||
image_cache: Arc<dyn ImageCache>,
|
image_cache: Arc<dyn ImageCache>,
|
||||||
browsing_context: Option<BrowsingContextId>,
|
browsing_context: Option<BrowsingContextId>,
|
||||||
gpu_id_hub: Arc<Mutex<Identities>>,
|
gpu_id_hub: Arc<Mutex<Identities>>,
|
||||||
) {
|
) -> JoinHandle<()> {
|
||||||
let serialized_worker_url = worker_url.to_string();
|
let serialized_worker_url = worker_url.to_string();
|
||||||
let name = format!("WebWorker for {}", serialized_worker_url);
|
let name = format!("WebWorker for {}", serialized_worker_url);
|
||||||
let top_level_browsing_context_id = TopLevelBrowsingContextId::installed();
|
let top_level_browsing_context_id = TopLevelBrowsingContextId::installed();
|
||||||
|
@ -435,7 +435,7 @@ impl DedicatedWorkerGlobalScope {
|
||||||
CommonScriptMsg::CollectReports,
|
CommonScriptMsg::CollectReports,
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.expect("Thread spawning failed");
|
.expect("Thread spawning failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn image_cache(&self) -> Arc<dyn ImageCache> {
|
pub fn image_cache(&self) -> Arc<dyn ImageCache> {
|
||||||
|
|
|
@ -112,15 +112,29 @@ use std::ops::Index;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::thread::JoinHandle;
|
||||||
use time::{get_time, Timespec};
|
use time::{get_time, Timespec};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
#[derive(JSTraceable)]
|
#[derive(JSTraceable)]
|
||||||
pub struct AutoCloseWorker(Arc<AtomicBool>);
|
pub struct AutoCloseWorker {
|
||||||
|
closing: Arc<AtomicBool>,
|
||||||
|
join_handle: Option<JoinHandle<()>>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Drop for AutoCloseWorker {
|
impl Drop for AutoCloseWorker {
|
||||||
|
/// <https://html.spec.whatwg.org/multipage/#terminate-a-worker>
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.0.store(true, Ordering::SeqCst);
|
// Step 1.
|
||||||
|
self.closing.store(true, Ordering::SeqCst);
|
||||||
|
|
||||||
|
// TODO: step 2 and 3.
|
||||||
|
// Step 4 is unnecessary since we don't use actual ports for dedicated workers.
|
||||||
|
self.join_handle
|
||||||
|
.take()
|
||||||
|
.expect("No handle to join on worker.")
|
||||||
|
.join()
|
||||||
|
.expect("Couldn't join on worker thread.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1794,10 +1808,13 @@ impl GlobalScope {
|
||||||
&self.permission_state_invocation_results
|
&self.permission_state_invocation_results
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn track_worker(&self, closing_worker: Arc<AtomicBool>) {
|
pub fn track_worker(&self, closing: Arc<AtomicBool>, join_handle: JoinHandle<()>) {
|
||||||
self.list_auto_close_worker
|
self.list_auto_close_worker
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.push(AutoCloseWorker(closing_worker));
|
.push(AutoCloseWorker {
|
||||||
|
closing,
|
||||||
|
join_handle: Some(join_handle),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn track_event_source(&self, event_source: &EventSource) {
|
pub fn track_event_source(&self, event_source: &EventSource) {
|
||||||
|
|
|
@ -45,7 +45,7 @@ use servo_config::pref;
|
||||||
use servo_rand::random;
|
use servo_rand::random;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::thread;
|
use std::thread::{self, JoinHandle};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use style::thread_state::{self, ThreadState};
|
use style::thread_state::{self, ThreadState};
|
||||||
|
|
||||||
|
@ -259,7 +259,7 @@ impl ServiceWorkerGlobalScope {
|
||||||
devtools_receiver: IpcReceiver<DevtoolScriptControlMsg>,
|
devtools_receiver: IpcReceiver<DevtoolScriptControlMsg>,
|
||||||
swmanager_sender: IpcSender<ServiceWorkerMsg>,
|
swmanager_sender: IpcSender<ServiceWorkerMsg>,
|
||||||
scope_url: ServoUrl,
|
scope_url: ServoUrl,
|
||||||
) {
|
) -> JoinHandle<()> {
|
||||||
let ScopeThings {
|
let ScopeThings {
|
||||||
script_url,
|
script_url,
|
||||||
init,
|
init,
|
||||||
|
@ -361,7 +361,7 @@ impl ServiceWorkerGlobalScope {
|
||||||
);
|
);
|
||||||
scope.clear_js_runtime();
|
scope.clear_js_runtime();
|
||||||
})
|
})
|
||||||
.expect("Thread spawning failed");
|
.expect("Thread spawning failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_mixed_message(&self, msg: MixedMessage) -> bool {
|
fn handle_mixed_message(&self, msg: MixedMessage) -> bool {
|
||||||
|
|
|
@ -87,7 +87,6 @@ impl Worker {
|
||||||
let (sender, receiver) = unbounded();
|
let (sender, receiver) = unbounded();
|
||||||
let closing = Arc::new(AtomicBool::new(false));
|
let closing = Arc::new(AtomicBool::new(false));
|
||||||
let worker = Worker::new(global, sender.clone(), closing.clone());
|
let worker = Worker::new(global, sender.clone(), closing.clone());
|
||||||
global.track_worker(closing.clone());
|
|
||||||
let worker_ref = Trusted::new(&*worker);
|
let worker_ref = Trusted::new(&*worker);
|
||||||
|
|
||||||
let worker_load_origin = WorkerScriptLoadOrigin {
|
let worker_load_origin = WorkerScriptLoadOrigin {
|
||||||
|
@ -125,7 +124,7 @@ impl Worker {
|
||||||
|
|
||||||
let init = prepare_workerscope_init(global, Some(devtools_sender), Some(worker_id));
|
let init = prepare_workerscope_init(global, Some(devtools_sender), Some(worker_id));
|
||||||
|
|
||||||
DedicatedWorkerGlobalScope::run_worker_scope(
|
let join_handle = DedicatedWorkerGlobalScope::run_worker_scope(
|
||||||
init,
|
init,
|
||||||
worker_url,
|
worker_url,
|
||||||
devtools_receiver,
|
devtools_receiver,
|
||||||
|
@ -136,12 +135,14 @@ impl Worker {
|
||||||
worker_load_origin,
|
worker_load_origin,
|
||||||
String::from(&*worker_options.name),
|
String::from(&*worker_options.name),
|
||||||
worker_options.type_,
|
worker_options.type_,
|
||||||
closing,
|
closing.clone(),
|
||||||
global.image_cache(),
|
global.image_cache(),
|
||||||
browsing_context,
|
browsing_context,
|
||||||
global.wgpu_id_hub(),
|
global.wgpu_id_hub(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
global.track_worker(closing, join_handle);
|
||||||
|
|
||||||
Ok(worker)
|
Ok(worker)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ use servo_config::pref;
|
||||||
use servo_url::ImmutableOrigin;
|
use servo_url::ImmutableOrigin;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::thread;
|
use std::thread::{self, JoinHandle};
|
||||||
|
|
||||||
enum Message {
|
enum Message {
|
||||||
FromResource(CustomResponseMediator),
|
FromResource(CustomResponseMediator),
|
||||||
|
@ -77,6 +77,18 @@ enum RegistrationUpdateTarget {
|
||||||
Active,
|
Active,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Drop for ServiceWorkerRegistration {
|
||||||
|
/// <https://html.spec.whatwg.org/multipage/#terminate-a-worker>
|
||||||
|
fn drop(&mut self) {
|
||||||
|
// TODO: Step 1, 2 and 3.
|
||||||
|
self.join_handle
|
||||||
|
.take()
|
||||||
|
.expect("No handle to join on worker.")
|
||||||
|
.join()
|
||||||
|
.expect("Couldn't join on worker thread.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// https://w3c.github.io/ServiceWorker/#service-worker-registration-concept
|
/// https://w3c.github.io/ServiceWorker/#service-worker-registration-concept
|
||||||
struct ServiceWorkerRegistration {
|
struct ServiceWorkerRegistration {
|
||||||
/// A unique identifer.
|
/// A unique identifer.
|
||||||
|
@ -87,6 +99,8 @@ struct ServiceWorkerRegistration {
|
||||||
waiting_worker: Option<ServiceWorker>,
|
waiting_worker: Option<ServiceWorker>,
|
||||||
/// https://w3c.github.io/ServiceWorker/#dfn-installing-worker
|
/// https://w3c.github.io/ServiceWorker/#dfn-installing-worker
|
||||||
installing_worker: Option<ServiceWorker>,
|
installing_worker: Option<ServiceWorker>,
|
||||||
|
/// A handle to join on the worker thread.
|
||||||
|
join_handle: Option<JoinHandle<()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServiceWorkerRegistration {
|
impl ServiceWorkerRegistration {
|
||||||
|
@ -96,9 +110,15 @@ impl ServiceWorkerRegistration {
|
||||||
active_worker: None,
|
active_worker: None,
|
||||||
waiting_worker: None,
|
waiting_worker: None,
|
||||||
installing_worker: None,
|
installing_worker: None,
|
||||||
|
join_handle: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn note_worker_thread(&mut self, join_handle: JoinHandle<()>) {
|
||||||
|
assert!(self.join_handle.is_none());
|
||||||
|
self.join_handle = Some(join_handle);
|
||||||
|
}
|
||||||
|
|
||||||
/// <https://w3c.github.io/ServiceWorker/#get-newest-worker>
|
/// <https://w3c.github.io/ServiceWorker/#get-newest-worker>
|
||||||
fn get_newest_worker(&self) -> Option<ServiceWorker> {
|
fn get_newest_worker(&self) -> Option<ServiceWorker> {
|
||||||
if let Some(worker) = self.active_worker.as_ref() {
|
if let Some(worker) = self.active_worker.as_ref() {
|
||||||
|
@ -326,9 +346,11 @@ impl ServiceWorkerManager {
|
||||||
|
|
||||||
// Very roughly steps 5 to 18.
|
// Very roughly steps 5 to 18.
|
||||||
// TODO: implement all steps precisely.
|
// TODO: implement all steps precisely.
|
||||||
let new_worker =
|
let (new_worker, join_handle) =
|
||||||
update_serviceworker(self.own_sender.clone(), job.scope_url.clone(), scope_things);
|
update_serviceworker(self.own_sender.clone(), job.scope_url.clone(), scope_things);
|
||||||
|
|
||||||
|
registration.note_worker_thread(join_handle);
|
||||||
|
|
||||||
// Step 19, run Install.
|
// Step 19, run Install.
|
||||||
|
|
||||||
// Install: Step 4, run Update Registration State.
|
// Install: Step 4, run Update Registration State.
|
||||||
|
@ -363,12 +385,12 @@ fn update_serviceworker(
|
||||||
own_sender: IpcSender<ServiceWorkerMsg>,
|
own_sender: IpcSender<ServiceWorkerMsg>,
|
||||||
scope_url: ServoUrl,
|
scope_url: ServoUrl,
|
||||||
scope_things: ScopeThings,
|
scope_things: ScopeThings,
|
||||||
) -> ServiceWorker {
|
) -> (ServiceWorker, JoinHandle<()>) {
|
||||||
let (sender, receiver) = unbounded();
|
let (sender, receiver) = unbounded();
|
||||||
let (_devtools_sender, devtools_receiver) = ipc::channel().unwrap();
|
let (_devtools_sender, devtools_receiver) = ipc::channel().unwrap();
|
||||||
let worker_id = ServiceWorkerId::new();
|
let worker_id = ServiceWorkerId::new();
|
||||||
|
|
||||||
ServiceWorkerGlobalScope::run_serviceworker_scope(
|
let join_handle = ServiceWorkerGlobalScope::run_serviceworker_scope(
|
||||||
scope_things.clone(),
|
scope_things.clone(),
|
||||||
sender.clone(),
|
sender.clone(),
|
||||||
receiver,
|
receiver,
|
||||||
|
@ -377,7 +399,10 @@ fn update_serviceworker(
|
||||||
scope_url.clone(),
|
scope_url.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
ServiceWorker::new(scope_things.script_url, sender, worker_id)
|
(
|
||||||
|
ServiceWorker::new(scope_things.script_url, sender, worker_id),
|
||||||
|
join_handle,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServiceWorkerManagerFactory for ServiceWorkerManager {
|
impl ServiceWorkerManagerFactory for ServiceWorkerManager {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue