make resource_thread talk to sw-manager

This commit is contained in:
Rahul Sharma 2016-07-18 19:06:48 +05:30
parent 1e6293ea1d
commit eff3e01df0
9 changed files with 125 additions and 109 deletions

View file

@ -35,7 +35,7 @@ use net_traits::bluetooth_thread::BluetoothMethodMsg;
use net_traits::filemanager_thread::FileManagerThreadMsg;
use net_traits::image_cache_thread::ImageCacheThread;
use net_traits::storage_thread::StorageThreadMsg;
use net_traits::{self, ResourceThreads, IpcSend, CustomResponseMediator, CoreResourceMsg};
use net_traits::{self, ResourceThreads, IpcSend};
use offscreen_gl_context::{GLContextAttributes, GLLimits};
use pipeline::{ChildProcess, InitialPipelineState, Pipeline};
use profile_traits::mem;
@ -98,9 +98,6 @@ pub struct Constellation<Message, LTF, STF> {
/// Receives messages from scripts.
script_receiver: Receiver<FromScriptMsg>,
/// Receive messages from resource thread
resource_receiver: Receiver<CustomResponseMediator>,
/// Receives messages from the compositor
compositor_receiver: Receiver<FromCompositorMsg>,
@ -440,13 +437,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
let (ipc_panic_sender, ipc_panic_receiver) = ipc::channel().expect("ipc channel failure");
let panic_receiver = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_panic_receiver);
let (resource_ipc_sender, resource_ipc_receiver) = ipc::channel().expect("ipc channel failure");
let resource_receiver = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(resource_ipc_receiver);
state.public_resource_threads.sender()
.send(CoreResourceMsg::NetworkMediator(resource_ipc_sender))
.expect("network sender sending failure");
let swmanager_receiver = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(swmanager_receiver);
let mut constellation: Constellation<Message, LTF, STF> = Constellation {
@ -467,7 +457,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
swmanager_chan: None,
swmanager_receiver: swmanager_receiver,
swmanager_sender: sw_mgr_clone,
resource_receiver: resource_receiver,
pipelines: HashMap::new(),
frames: HashMap::new(),
subpage_map: HashMap::new(),
@ -638,8 +627,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
Compositor(FromCompositorMsg),
Layout(FromLayoutMsg),
Panic(PanicMsg),
FromSWManager(SWManagerMsg),
FromResource(CustomResponseMediator),
FromSWManager(SWManagerMsg)
}
// Get one incoming request.
@ -659,7 +647,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
let receiver_from_layout = &self.layout_receiver;
let receiver_from_panic = &self.panic_receiver;
let receiver_from_swmanager = &self.swmanager_receiver;
let receiver_from_resource = &self.resource_receiver;
select! {
msg = receiver_from_script.recv() =>
Request::Script(msg.expect("Unexpected script channel panic in constellation")),
@ -670,9 +657,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
msg = receiver_from_panic.recv() =>
Request::Panic(msg.expect("Unexpected panic channel panic in constellation")),
msg = receiver_from_swmanager.recv() =>
Request::FromSWManager(msg.expect("Unexpected panic channel panic in constellation")),
msg = receiver_from_resource.recv() =>
Request::FromResource(msg.expect("Unexpected panic channel panic in constellation"))
Request::FromSWManager(msg.expect("Unexpected panic channel panic in constellation"))
}
};
@ -692,9 +677,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
Request::FromSWManager(message) => {
self.handle_request_from_swmanager(message);
}
Request::FromResource(message) => {
self.handle_request_from_resource(message);
}
}
}
@ -707,14 +689,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
}
fn handle_request_from_resource(&self, mediator: CustomResponseMediator) {
if let Some(ref mgr) = self.swmanager_chan {
let _ = mgr.send(ServiceWorkerMsg::ActivateWorker(mediator));
} else {
warn!("activation request to service worker manager failed");
}
}
fn handle_request_from_compositor(&mut self, message: FromCompositorMsg) {
match message {
FromCompositorMsg::Exit => {
@ -985,10 +959,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
FromScriptMsg::GetScrollOffset(pid, lid, send) => {
self.compositor_proxy.send(ToCompositorMsg::GetScrollOffset(pid, lid, send));
}
FromScriptMsg::NetworkRequest(mediator) => {
debug!("activation request for service worker received");
self.handle_activate_worker(mediator);
}
FromScriptMsg::RegisterServiceWorker(scope_things, scope) => {
debug!("constellation got store registration scope message");
self.handle_register_serviceworker(scope_things, scope);
@ -1028,14 +998,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
}
fn handle_activate_worker(&self, mediator: CustomResponseMediator) {
if let Some(ref mgr) = self.swmanager_chan {
let _ = mgr.send(ServiceWorkerMsg::ActivateWorker(mediator));
} else {
warn!("activation request to service worker manager failed");
}
}
fn handle_exit(&mut self) {
// TODO: add a timer, which forces shutdown if threads aren't responsive.
if self.shutting_down { return; }

View file

@ -19,13 +19,13 @@ use layers::geometry::DevicePixel;
use layout_traits::LayoutThreadFactory;
use msg::constellation_msg::{FrameId, FrameType, LoadData, PanicMsg, PipelineId};
use msg::constellation_msg::{PipelineNamespaceId, SubpageId};
use net_traits::ResourceThreads;
use net_traits::bluetooth_thread::BluetoothMethodMsg;
use net_traits::image_cache_thread::ImageCacheThread;
use net_traits::{ResourceThreads, IpcSend};
use profile_traits::mem as profile_mem;
use profile_traits::time;
use script_traits::{ConstellationControlMsg, InitialScriptState, MozBrowserEvent};
use script_traits::{LayoutControlMsg, LayoutMsg, NewLayoutInfo, ScriptMsg, SWManagerMsg};
use script_traits::{LayoutControlMsg, LayoutMsg, NewLayoutInfo, ScriptMsg, SWManagerMsg, SWManagerSenders};
use script_traits::{ScriptThreadFactory, TimerEventRequest, WindowSizeData};
use std::collections::HashMap;
use std::io::Error as IOError;
@ -551,7 +551,10 @@ impl UnprivilegedPipelineContent {
self.prefs.clone()
}
pub fn swmanager_chan(&self) -> IpcSender<SWManagerMsg> {
self.swmanager_thread.clone()
pub fn swmanager_senders(&self) -> SWManagerSenders {
SWManagerSenders {
swmanager_sender: self.swmanager_thread.clone(),
resource_sender: self.resource_threads.sender()
}
}
}

View file

@ -59,7 +59,7 @@ pub fn factory(user_agent: String,
http_state: HttpState,
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
profiler_chan: ProfilerChan,
constellation_chan: Option<IpcSender<CustomResponseMediator>>,
swmanager_chan: Option<IpcSender<CustomResponseMediator>>,
connector: Arc<Pool<Connector>>)
-> Box<FnBox(LoadData,
LoadConsumer,
@ -79,7 +79,7 @@ pub fn factory(user_agent: String,
connector,
http_state,
devtools_chan,
constellation_chan,
swmanager_chan,
cancel_listener,
user_agent)
})
@ -133,7 +133,7 @@ fn load_for_consumer(load_data: LoadData,
connector: Arc<Pool<Connector>>,
http_state: HttpState,
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
constellation_chan: Option<IpcSender<CustomResponseMediator>>,
swmanager_chan: Option<IpcSender<CustomResponseMediator>>,
cancel_listener: CancellationListener,
user_agent: String) {
let factory = NetworkHttpRequestFactory {
@ -143,7 +143,7 @@ fn load_for_consumer(load_data: LoadData,
let ui_provider = TFDProvider;
match load(&load_data, &ui_provider, &http_state,
devtools_chan, &factory,
user_agent, &cancel_listener, constellation_chan) {
user_agent, &cancel_listener, swmanager_chan) {
Err(error) => {
match error.error {
LoadErrorType::ConnectionAborted { .. } => unreachable!(),
@ -864,7 +864,7 @@ pub fn load<A, B>(load_data: &LoadData,
request_factory: &HttpRequestFactory<R=A>,
user_agent: String,
cancel_listener: &CancellationListener,
constellation_chan: Option<IpcSender<CustomResponseMediator>>)
swmanager_chan: Option<IpcSender<CustomResponseMediator>>)
-> Result<StreamedResponse, LoadError> where A: HttpRequest + 'static, B: UIProvider {
let max_redirects = PREFS.get("network.http.redirection-limit").as_i64().unwrap() as u32;
let mut iters = 0;
@ -886,9 +886,9 @@ pub fn load<A, B>(load_data: &LoadData,
response_chan: msg_sender,
load_url: doc_url.clone()
};
if let Some(sender) = constellation_chan {
if let Some(sender) = swmanager_chan {
let _ = sender.send(response_mediator);
if let Ok(Some(custom_response)) = msg_receiver.try_recv() {
if let Ok(Some(custom_response)) = msg_receiver.recv() {
let metadata = Metadata::default(doc_url.clone());
let readable_response = to_readable_response(custom_response);
return StreamedResponse::from_http_response(box readable_response, metadata);

View file

@ -280,7 +280,7 @@ impl ResourceChannelManager {
consumer.send(cookie_jar.cookies_for_url(&url, source)).unwrap();
}
CoreResourceMsg::NetworkMediator(mediator_chan) => {
self.resource_manager.constellation_chan = Some(mediator_chan)
self.resource_manager.swmanager_chan = Some(mediator_chan)
}
CoreResourceMsg::GetCookiesDataForUrl(url, consumer, source) => {
let mut cookie_jar = group.cookie_jar.write().unwrap();
@ -459,7 +459,7 @@ pub struct CoreResourceManager {
user_agent: String,
mime_classifier: Arc<MimeClassifier>,
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
constellation_chan: Option<IpcSender<CustomResponseMediator>>,
swmanager_chan: Option<IpcSender<CustomResponseMediator>>,
profiler_chan: ProfilerChan,
filemanager_chan: IpcSender<FileManagerThreadMsg>,
cancel_load_map: HashMap<ResourceId, Sender<()>>,
@ -475,7 +475,7 @@ impl CoreResourceManager {
user_agent: user_agent,
mime_classifier: Arc::new(MimeClassifier::new()),
devtools_chan: devtools_channel,
constellation_chan: None,
swmanager_chan: None,
profiler_chan: profiler_chan,
filemanager_chan: filemanager_chan,
cancel_load_map: HashMap::new(),
@ -547,7 +547,7 @@ impl CoreResourceManager {
http_state,
self.devtools_chan.clone(),
self.profiler_chan.clone(),
self.constellation_chan.clone(),
self.swmanager_chan.clone(),
resource_grp.connector.clone())
},
"data" => from_factory(data_loader::factory),

View file

@ -114,9 +114,8 @@ mod unpremultiplytable;
mod webdriver_handlers;
use dom::bindings::codegen::RegisterBindings;
use ipc_channel::ipc::IpcSender;
use js::jsapi::{Handle, JSContext, JSObject, SetDOMProxyInformation};
use script_traits::SWManagerMsg;
use script_traits::SWManagerSenders;
use serviceworker_manager::ServiceWorkerManager;
use std::ptr;
use util::opts;
@ -163,13 +162,13 @@ fn perform_platform_specific_initialization() {
fn perform_platform_specific_initialization() {}
#[allow(unsafe_code)]
pub fn init(from_swmanager_sender: IpcSender<SWManagerMsg>) {
pub fn init(sw_senders: SWManagerSenders) {
unsafe {
SetDOMProxyInformation(ptr::null(), 0, Some(script_thread::shadow_check_callback));
}
// Spawn the service worker manager passing the constellation sender
ServiceWorkerManager::spawn_manager(from_swmanager_sender);
ServiceWorkerManager::spawn_manager(sw_senders);
// Create the global vtables used by the (generated) DOM
// bindings to implement JS proxies.

View file

@ -10,10 +10,12 @@
use devtools_traits::{DevtoolsPageInfo, ScriptToDevtoolsControlMsg};
use dom::serviceworkerglobalscope::ServiceWorkerGlobalScope;
use dom::serviceworkerregistration::longest_prefix_match;
use ipc_channel::ipc::{self, IpcSender, IpcReceiver};
use script_traits::{ServiceWorkerMsg, ScopeThings, SWManagerMsg};
use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::router::ROUTER;
use net_traits::{CustomResponseMediator, CoreResourceMsg};
use script_traits::{ServiceWorkerMsg, ScopeThings, SWManagerMsg, SWManagerSenders};
use std::collections::HashMap;
use std::sync::mpsc::channel;
use std::sync::mpsc::{channel, Receiver};
use url::Url;
use util::thread::spawn_named;
@ -25,25 +27,33 @@ pub struct ServiceWorkerManager {
// own sender to send messages here
own_sender: IpcSender<ServiceWorkerMsg>,
// receiver to receive messages from constellation
own_port: IpcReceiver<ServiceWorkerMsg>,
own_port: Receiver<ServiceWorkerMsg>,
// to receive resource messages
resource_receiver: Receiver<CustomResponseMediator>
}
impl ServiceWorkerManager {
fn new(own_sender: IpcSender<ServiceWorkerMsg>,
from_constellation_receiver: IpcReceiver<ServiceWorkerMsg>) -> ServiceWorkerManager {
from_constellation_receiver: Receiver<ServiceWorkerMsg>,
resource_port: Receiver<CustomResponseMediator>) -> ServiceWorkerManager {
ServiceWorkerManager {
registered_workers: HashMap::new(),
active_workers: HashMap::new(),
own_sender: own_sender,
own_port: from_constellation_receiver
own_port: from_constellation_receiver,
resource_receiver: resource_port
}
}
pub fn spawn_manager(from_swmanager_sender: IpcSender<SWManagerMsg>) {
pub fn spawn_manager(sw_senders: SWManagerSenders) {
let (own_sender, from_constellation_receiver) = ipc::channel().unwrap();
from_swmanager_sender.send(SWManagerMsg::OwnSender(own_sender.clone())).unwrap();
let (resource_chan, resource_port) = ipc::channel().unwrap();
let from_constellation = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(from_constellation_receiver);
let resource_port = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(resource_port);
let _ = sw_senders.resource_sender.send(CoreResourceMsg::NetworkMediator(resource_chan));
let _ = sw_senders.swmanager_sender.send(SWManagerMsg::OwnSender(own_sender.clone()));
spawn_named("ServiceWorkerManager".to_owned(), move || {
ServiceWorkerManager::new(own_sender, from_constellation_receiver).start();
ServiceWorkerManager::new(own_sender, from_constellation, resource_port).handle_message();
});
}
@ -83,7 +93,7 @@ impl ServiceWorkerManager {
devtools_receiver,
self.own_sender.clone(),
scope_url.clone());
// store the worker in active_workers map
// We store the activated worker
self.active_workers.insert(scope_url.clone(), scope_things.clone());
} else {
warn!("Unable to activate service worker");
@ -91,33 +101,63 @@ impl ServiceWorkerManager {
}
}
fn start(&mut self) {
while let Ok(msg) = self.own_port.recv() {
match msg {
ServiceWorkerMsg::RegisterServiceWorker(scope_things, scope) => {
if self.registered_workers.contains_key(&scope) {
warn!("ScopeThings for {:?} already stored in SW-Manager", scope);
} else {
self.registered_workers.insert(scope, scope_things);
}
}
ServiceWorkerMsg::Timeout(scope) => {
if self.active_workers.contains_key(&scope) {
let _ = self.active_workers.remove(&scope);
} else {
warn!("ScopeThings for {:?} is not active", scope);
}
}
ServiceWorkerMsg::ActivateWorker(mediator) => {
self.prepare_activation(&mediator.load_url);
// TODO XXXcreativcoder this net_sender will need to be send to the appropriate service worker
// so that it may do the sending of custom responses.
// For now we just send a None from here itself
let _ = mediator.response_chan.send(None);
fn handle_message(&mut self) {
while self.receive_message() {
// process message
}
}
fn handle_message_from_constellation(&mut self, msg: ServiceWorkerMsg) -> bool {
match msg {
ServiceWorkerMsg::RegisterServiceWorker(scope_things, scope) => {
if self.registered_workers.contains_key(&scope) {
warn!("ScopeThings for {:?} already stored in SW-Manager", scope);
} else {
self.registered_workers.insert(scope, scope_things);
}
ServiceWorkerMsg::Exit => break
true
}
ServiceWorkerMsg::Timeout(scope) => {
if self.active_workers.contains_key(&scope) {
let _ = self.active_workers.remove(&scope);
} else {
warn!("ScopeThings for {:?} is not active", scope);
}
true
}
ServiceWorkerMsg::Exit => false
}
}
#[inline]
fn handle_message_from_resource(&mut self, mediator: CustomResponseMediator) -> bool {
self.prepare_activation(&mediator.load_url);
// TODO XXXcreativcoder This mediator will need to be send to the appropriate service worker
// so that it may do the sending of custom responses.
// For now we just send a None from here itself
let _ = mediator.response_chan.send(None);
true
}
#[allow(unsafe_code)]
fn receive_message(&mut self) -> bool {
enum Message {
FromResource(CustomResponseMediator),
FromConstellation(ServiceWorkerMsg)
}
let message = {
let msg_from_constellation = &self.own_port;
let msg_from_resource = &self.resource_receiver;
select! {
msg = msg_from_constellation.recv() =>
Message::FromConstellation(msg.expect("Unexpected constellation channel panic in sw-manager")),
msg = msg_from_resource.recv() =>
Message::FromResource(msg.expect("Unexpected resource channel panic in sw-manager"))
}
};
match message {
Message::FromConstellation(msg) => self.handle_message_from_constellation(msg),
Message::FromResource(mediator) => self.handle_message_from_resource(mediator)
}
}
}

View file

@ -68,7 +68,7 @@ use util::ipc::OptionalOpaqueIpcSender;
use webdriver_msg::{LoadStatus, WebDriverScriptCommand};
pub use script_msg::{LayoutMsg, ScriptMsg, EventResult, LogEntry};
pub use script_msg::{ServiceWorkerMsg, ScopeThings, SWManagerMsg};
pub use script_msg::{ServiceWorkerMsg, ScopeThings, SWManagerMsg, SWManagerSenders};
/// The address of a node. Layout sends these back. They must be validated via
/// `from_untrusted_node_address` before they can be used, because we do not trust layout.

View file

@ -18,7 +18,7 @@ use gfx_traits::LayerId;
use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::{Key, KeyModifiers, KeyState, LoadData};
use msg::constellation_msg::{NavigationDirection, PipelineId, SubpageId};
use net_traits::CustomResponseMediator;
use net_traits::CoreResourceMsg;
use offscreen_gl_context::{GLContextAttributes, GLLimits};
use style_traits::cursor::Cursor;
use style_traits::viewport::ViewportConstraints;
@ -110,8 +110,6 @@ pub enum ScriptMsg {
ActivateDocument(PipelineId),
/// Set the document state for a pipeline (used by screenshot / reftests)
SetDocumentState(PipelineId, DocumentState),
/// Message from network to constellation
NetworkRequest(CustomResponseMediator),
/// Update the pipeline Url, which can change after redirections.
SetFinalUrl(PipelineId, Url),
/// Check if an alert dialog box should be presented
@ -160,20 +158,26 @@ pub struct ScopeThings {
pub worker_id: WorkerId,
}
/// Channels to allow service worker manager to communicate with constellation and resource thread
pub struct SWManagerSenders {
/// sender for communicating with constellation
pub swmanager_sender: IpcSender<SWManagerMsg>,
/// sender for communicating with resource thread
pub resource_sender: IpcSender<CoreResourceMsg>
}
/// Messages sent to Service Worker Manager thread
#[derive(Deserialize, Serialize)]
pub enum ServiceWorkerMsg {
/// Message to register the service worker
RegisterServiceWorker(ScopeThings, Url),
/// Message to activate the worker
ActivateWorker(CustomResponseMediator),
/// Timeout message sent by active service workers
Timeout(Url),
/// Exit the service worker manager
Exit,
}
/// Messages outgoing from the Service Worker Manager thread
/// Messages outgoing from the Service Worker Manager thread to constellation
#[derive(Deserialize, Serialize)]
pub enum SWManagerMsg {
/// Provide the constellation with a means of communicating with the Service Worker Manager

View file

@ -83,7 +83,7 @@ use profile::mem as profile_mem;
use profile::time as profile_time;
use profile_traits::mem;
use profile_traits::time;
use script_traits::{ConstellationMsg, ScriptMsg, SWManagerMsg};
use script_traits::{ConstellationMsg, ScriptMsg, SWManagerSenders};
use std::cmp::max;
use std::rc::Rc;
use std::sync::mpsc::Sender;
@ -159,7 +159,7 @@ impl<Window> Browser<Window> where Window: WindowMethods + 'static {
// Create the constellation, which maintains the engine
// pipelines, including the script and layout threads, as well
// as the navigation context.
let (constellation_chan, swmanager_sender) = create_constellation(opts.clone(),
let (constellation_chan, sw_senders) = create_constellation(opts.clone(),
compositor_proxy.clone_compositor_proxy(),
time_profiler_chan.clone(),
mem_profiler_chan.clone(),
@ -168,7 +168,7 @@ impl<Window> Browser<Window> where Window: WindowMethods + 'static {
webrender_api_sender.clone());
// Send the constellation's swmanager sender to service worker manager thread
script::init(swmanager_sender);
script::init(sw_senders);
if cfg!(feature = "webdriver") {
if let Some(port) = opts.webdriver_port {
@ -230,7 +230,7 @@ fn create_constellation(opts: opts::Opts,
devtools_chan: Option<Sender<devtools_traits::DevtoolsControlMsg>>,
supports_clipboard: bool,
webrender_api_sender: Option<webrender_traits::RenderApiSender>)
-> (Sender<ConstellationMsg>, IpcSender<SWManagerMsg>) {
-> (Sender<ConstellationMsg>, SWManagerSenders) {
let bluetooth_thread: IpcSender<BluetoothMethodMsg> = BluetoothThreadFactory::new();
let (public_resource_threads, private_resource_threads) =
@ -242,6 +242,8 @@ fn create_constellation(opts: opts::Opts,
let font_cache_thread = FontCacheThread::new(public_resource_threads.sender(),
webrender_api_sender.as_ref().map(|wr| wr.create_api()));
let resource_sender = public_resource_threads.sender();
let initial_state = InitialConstellationState {
compositor_proxy: compositor_proxy,
devtools_chan: devtools_chan,
@ -264,7 +266,13 @@ fn create_constellation(opts: opts::Opts,
constellation_chan.send(ConstellationMsg::InitLoadUrl(url)).unwrap();
};
(constellation_chan, from_swmanager_sender)
// channels to communicate with Service Worker Manager
let sw_senders = SWManagerSenders {
swmanager_sender: from_swmanager_sender,
resource_sender: resource_sender
};
(constellation_chan, sw_senders)
}
// A logger that logs to two downstream loggers.
@ -311,9 +319,9 @@ pub fn run_content_process(token: String) {
create_sandbox();
}
// Send the constellation sender to service worker manager thread
let from_swmanager_sender = unprivileged_content.swmanager_chan();
script::init(from_swmanager_sender);
// send the required channels to the service worker manager
let sw_senders = unprivileged_content.swmanager_senders();
script::init(sw_senders);
unprivileged_content.start_all::<script_layout_interface::message::Msg,
layout_thread::LayoutThread,