Auto merge of #26087 - gterzian:allow_service_workers_in_multiprocess, r=jdm

Fix ServiceWorker in multiprocess

<!-- Please describe your changes on the following line: -->

FIX #15217
FIX #26100

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [ ] `./mach build -d` does not report any errors
- [ ] `./mach test-tidy` does not report any errors
- [ ] These changes fix #___ (GitHub issue number if applicable)

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because ___

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
This commit is contained in:
bors-servo 2020-04-05 11:02:08 -04:00 committed by GitHub
commit ae49473c25
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 415 additions and 267 deletions

View file

@ -5,8 +5,6 @@
use crate::dom::bindings::codegen::RegisterBindings;
use crate::dom::bindings::proxyhandler;
use crate::script_runtime::JSEngineSetup;
use crate::serviceworker_manager::ServiceWorkerManager;
use script_traits::SWManagerSenders;
#[cfg(target_os = "linux")]
#[allow(unsafe_code)]
@ -51,11 +49,6 @@ fn perform_platform_specific_initialization() {
#[cfg(not(target_os = "linux"))]
fn perform_platform_specific_initialization() {}
pub fn init_service_workers(sw_senders: SWManagerSenders) {
// Spawn the service worker manager passing the constellation sender
ServiceWorkerManager::spawn_manager(sw_senders);
}
#[allow(unsafe_code)]
pub fn init() -> JSEngineSetup {
unsafe {

View file

@ -91,7 +91,7 @@ pub mod script_runtime;
#[allow(unsafe_code)]
pub mod script_thread;
#[warn(deprecated)]
mod serviceworker_manager;
pub mod serviceworker_manager;
#[warn(deprecated)]
mod serviceworkerjob;
#[warn(deprecated)]
@ -115,7 +115,7 @@ mod unpremultiplytable;
#[warn(deprecated)]
mod webdriver_handlers;
pub use init::{init, init_service_workers};
pub use init::init;
pub use script_runtime::JSEngineSetup;
/// A module with everything layout can use from script.

View file

@ -15,8 +15,12 @@ use devtools_traits::{DevtoolsPageInfo, ScriptToDevtoolsControlMsg};
use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::router::ROUTER;
use net_traits::{CoreResourceMsg, CustomResponseMediator};
use script_traits::{DOMMessage, SWManagerMsg, SWManagerSenders, ScopeThings, ServiceWorkerMsg};
use script_traits::{
DOMMessage, SWManagerMsg, SWManagerSenders, ScopeThings, ServiceWorkerManagerFactory,
ServiceWorkerMsg,
};
use servo_config::pref;
use servo_url::ImmutableOrigin;
use servo_url::ServoUrl;
use std::collections::HashMap;
use std::thread;
@ -31,6 +35,9 @@ pub struct ServiceWorkerManager {
registered_workers: HashMap<ServoUrl, ScopeThings>,
// map of active service worker descriptors
active_workers: HashMap<ServoUrl, Sender<ServiceWorkerScriptMsg>>,
// Will be useful to implement posting a message to a client.
// See https://github.com/servo/servo/issues/24660
_constellation_sender: IpcSender<SWManagerMsg>,
// own sender to send messages here
own_sender: IpcSender<ServiceWorkerMsg>,
// receiver to receive messages from constellation
@ -44,6 +51,7 @@ impl ServiceWorkerManager {
own_sender: IpcSender<ServiceWorkerMsg>,
from_constellation_receiver: Receiver<ServiceWorkerMsg>,
resource_port: Receiver<CustomResponseMediator>,
constellation_sender: IpcSender<SWManagerMsg>,
) -> ServiceWorkerManager {
ServiceWorkerManager {
registered_workers: HashMap::new(),
@ -51,30 +59,10 @@ impl ServiceWorkerManager {
own_sender: own_sender,
own_port: from_constellation_receiver,
resource_receiver: resource_port,
_constellation_sender: constellation_sender,
}
}
pub fn spawn_manager(sw_senders: SWManagerSenders) {
let (own_sender, from_constellation_receiver) = ipc::channel().unwrap();
let (resource_chan, resource_port) = ipc::channel().unwrap();
let from_constellation =
ROUTER.route_ipc_receiver_to_new_crossbeam_receiver(from_constellation_receiver);
let resource_port = ROUTER.route_ipc_receiver_to_new_crossbeam_receiver(resource_port);
let _ = sw_senders
.resource_sender
.send(CoreResourceMsg::NetworkMediator(resource_chan));
let _ = sw_senders
.swmanager_sender
.send(SWManagerMsg::OwnSender(own_sender.clone()));
thread::Builder::new()
.name("ServiceWorkerManager".to_owned())
.spawn(move || {
ServiceWorkerManager::new(own_sender, from_constellation, resource_port)
.handle_message();
})
.expect("Thread spawning failed");
}
pub fn get_matching_scope(&self, load_url: &ServoUrl) -> Option<ServoUrl> {
for scope in self.registered_workers.keys() {
if longest_prefix_match(&scope, load_url) {
@ -203,6 +191,38 @@ impl ServiceWorkerManager {
}
}
impl ServiceWorkerManagerFactory for ServiceWorkerManager {
fn create(sw_senders: SWManagerSenders, origin: ImmutableOrigin) {
let (resource_chan, resource_port) = ipc::channel().unwrap();
let SWManagerSenders {
resource_sender,
own_sender,
receiver,
swmanager_sender: constellation_sender,
} = sw_senders;
let from_constellation = ROUTER.route_ipc_receiver_to_new_crossbeam_receiver(receiver);
let resource_port = ROUTER.route_ipc_receiver_to_new_crossbeam_receiver(resource_port);
let _ = resource_sender.send(CoreResourceMsg::NetworkMediator(resource_chan, origin));
if thread::Builder::new()
.name("ServiceWorkerManager".to_owned())
.spawn(move || {
ServiceWorkerManager::new(
own_sender,
from_constellation,
resource_port,
constellation_sender,
)
.handle_message();
})
.is_err()
{
warn!("ServiceWorkerManager thread spawning failed");
}
}
}
pub fn serviceworker_enabled() -> bool {
pref!(dom.serviceworker.enabled)
}