Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Allow for a service worker manager per origin in multiprocess #26073

Closed
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

allow for a service worker manager per origin in multiprocess

  • Loading branch information
gterzian committed Mar 31, 2020
commit e0bd24065b8c7ac7c94036a6302e1bccab2c2692
@@ -348,8 +348,12 @@ pub struct Constellation<Message, LTF, STF> {
/// bluetooth thread.
bluetooth_thread: IpcSender<BluetoothRequest>,

/// An IPC channel for the constellation to send messages to the
/// Service Worker Manager thread.
/// A map of origin to ServiceWorker manager sender,
/// for use in multi-process mode.
serviceworker_managers: HashMap<ImmutableOrigin, IpcSender<ServiceWorkerMsg>>,

/// The sender to a single ServiceWorker manager
/// for use in single-process mode.
swmanager_chan: Option<IpcSender<ServiceWorkerMsg>>,

/// An IPC channel for Service Worker Manager threads to send
@@ -961,6 +965,7 @@ where
public_resource_threads: state.public_resource_threads,
private_resource_threads: state.private_resource_threads,
font_cache_thread: state.font_cache_thread,
serviceworker_managers: HashMap::new(),
swmanager_chan: None,
swmanager_receiver: swmanager_receiver,
swmanager_sender: sw_mgr_clone,
@@ -1530,9 +1535,17 @@ where

fn handle_request_from_swmanager(&mut self, message: SWManagerMsg) {
match message {
SWManagerMsg::OwnSender(sw_sender) => {
// store service worker manager for communicating with it.
self.swmanager_chan = Some(sw_sender);
SWManagerMsg::OwnSender(sw_sender, origin) => {
if let Some(origin) = origin {
// Multiple processes.
self.serviceworker_managers.insert(sw_sender, origin);
} else {
// A single process.
self.swmanager_chan = Some(sw_sender);
}
},
SWManagerMsg::ShouldStartManagerForOrigin(sender, origin) => {
let _ = sender.send(!self.serviceworker_managers.contains_key(&origin));
},
}
}
@@ -1968,7 +1981,11 @@ where
if let Some(ref mgr) = self.swmanager_chan {
let _ = mgr.send(ServiceWorkerMsg::ForwardDOMMessage(msg_vec, scope_url));
} else {
warn!("Unable to forward DOMMessage for postMessage call");
if let Some(mgr) = self.serviceworker_managers.get(&scope_url.origin()) {
let _ = mgr.send(ServiceWorkerMsg::ForwardDOMMessage(msg_vec, scope_url));
} else {
warn!("Unable to forward DOMMessage for postMessage call");
}
}
},
FromScriptMsg::BroadcastStorageEvent(storage, url, key, old_value, new_value) => {
@@ -2625,7 +2642,11 @@ where
if let Some(ref mgr) = self.swmanager_chan {
let _ = mgr.send(ServiceWorkerMsg::RegisterServiceWorker(scope_things, scope));
} else {
warn!("sending scope info to service worker manager failed");
if let Some(mgr) = self.serviceworker_managers.get(&scope_url.origin()) {
let _ = mgr.send(ServiceWorkerMsg::RegisterServiceWorker(scope_things, scope));
} else {
warn!("Unable to forward DOMMessage for postMessage call");
}
}
}

@@ -2762,11 +2783,17 @@ where
warn!("Exit bluetooth thread failed ({})", e);
}

debug!("Exiting service worker manager thread.");
debug!("Exiting service worker manager(s).");
if let Some(mgr) = self.swmanager_chan.as_ref() {
if let Err(e) = mgr.send(ServiceWorkerMsg::Exit) {
warn!("Exit service worker manager failed ({})", e);
}
} else {
for (_, mgr) in self.serviceworker_managers.drain() {
if let Err(e) = mgr.send(ServiceWorkerMsg::Exit) {
warn!("Exit service worker manager failed ({})", e);
}
}
}

debug!("Exiting Canvas Paint thread.");
@@ -7,6 +7,7 @@ use crate::dom::bindings::proxyhandler;
use crate::script_runtime::JSEngineSetup;
use crate::serviceworker_manager::ServiceWorkerManager;
use script_traits::SWManagerSenders;
use servo_url::ImmutableOrigin;

#[cfg(target_os = "linux")]
#[allow(unsafe_code)]
@@ -51,9 +52,9 @@ fn perform_platform_specific_initialization() {
#[cfg(not(target_os = "linux"))]
fn perform_platform_specific_initialization() {}

pub fn init_service_workers(sw_senders: SWManagerSenders) {
pub fn init_service_workers(sw_senders: SWManagerSenders, origin: Option<ImmutableOrigin>) {
// Spawn the service worker manager passing the constellation sender
ServiceWorkerManager::spawn_manager(sw_senders);
ServiceWorkerManager::spawn_manager(sw_senders, origin);
}

#[allow(unsafe_code)]
@@ -54,8 +54,26 @@ impl ServiceWorkerManager {
}
}

pub fn spawn_manager(sw_senders: SWManagerSenders) {
pub fn spawn_manager(sw_senders: SWManagerSenders, origin: Option<ImmutableOrigin>) {
let (own_sender, from_constellation_receiver) = ipc::channel().unwrap();

if let Some(origin) = origin.as_ref() {
let (sender, receiver) = ipc::channel().unwrap();
let _ = sw_senders
.swmanager_sender
.send(SWManagerMsg::ShouldStartManagerForOrigin(
sender,
origin.clone(),
));
if !receiver
.recv()
.expect("Couldn't get a confirmation from the constellation.")
{
// No need to start a manager in this process.
return;
}
}

let (resource_chan, resource_port) = ipc::channel().unwrap();
let from_constellation =
ROUTER.route_ipc_receiver_to_new_crossbeam_receiver(from_constellation_receiver);
@@ -65,7 +83,7 @@ impl ServiceWorkerManager {
.send(CoreResourceMsg::NetworkMediator(resource_chan));
let _ = sw_senders
.swmanager_sender
.send(SWManagerMsg::OwnSender(own_sender.clone()));
.send(SWManagerMsg::OwnSender(own_sender.clone(), origin));
thread::Builder::new()
.name("ServiceWorkerManager".to_owned())
.spawn(move || {
@@ -394,5 +394,8 @@ pub enum ServiceWorkerMsg {
#[derive(Debug, Deserialize, Serialize)]
pub enum SWManagerMsg {
/// Provide the constellation with a means of communicating with the Service Worker Manager
OwnSender(IpcSender<ServiceWorkerMsg>),
OwnSender(IpcSender<ServiceWorkerMsg>, Option<ImmutableOrigin>),
/// In multi-process mode, ask the constellation
/// whether a given content-process should start a SW manager.
ShouldStartManagerForOrigin(IpcSender<bool>, ImmutableOrigin),
}
@@ -540,8 +540,10 @@ where
pending_wr_frame.clone(),
);

// Send the constellation's swmanager sender to service worker manager thread
script::init_service_workers(sw_senders);
if !opts.multiprocess {
// Send the constellation's swmanager sender to service worker manager thread
script::init_service_workers(sw_senders, None);
}

if cfg!(feature = "webdriver") {
if let Some(port) = opts.webdriver_port {
@@ -1021,7 +1023,9 @@ pub fn run_content_process(token: String) {
// send the required channels to the service worker manager
let sw_senders = unprivileged_content.swmanager_senders();
let _js_engine_setup = script::init();
script::init_service_workers(sw_senders);

let origin = unprivileged_content.load_data.url.origin();
script::init_service_workers(sw_senders, Some(origin));

media_platform::init();

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.