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

Integrate service worker manager thread #11727

Merged
merged 2 commits into from Jul 18, 2016
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Next

Integrate service worker manager thread

  • Loading branch information
creativcoder committed Jul 16, 2016
commit 1e6293ea1d06120c9f3488d7d32c24d8d92df6b1
@@ -35,19 +35,20 @@ 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};
use net_traits::{self, ResourceThreads, IpcSend, CustomResponseMediator, CoreResourceMsg};
use offscreen_gl_context::{GLContextAttributes, GLLimits};
use pipeline::{ChildProcess, InitialPipelineState, Pipeline};
use profile_traits::mem;
use profile_traits::time;
use rand::{random, Rng, SeedableRng, StdRng};
use script_traits::webdriver_msg;
use script_traits::{AnimationState, AnimationTickType, CompositorEvent};
use script_traits::{ConstellationControlMsg, ConstellationMsg as FromCompositorMsg};
use script_traits::{DocumentState, LayoutControlMsg};
use script_traits::{IFrameLoadInfo, IFrameSandboxState, TimerEventRequest};
use script_traits::{LayoutMsg as FromLayoutMsg, ScriptMsg as FromScriptMsg, ScriptThreadFactory};
use script_traits::{LogEntry, MozBrowserEvent, MozBrowserErrorType, WebDriverCommandMsg, WindowSizeData};
use script_traits::{MozBrowserEvent, MozBrowserErrorType, WebDriverCommandMsg, WindowSizeData};
use script_traits::{ScopeThings, SWManagerMsg};
use script_traits::{webdriver_msg, LogEntry, ServiceWorkerMsg};
use std::borrow::ToOwned;
use std::collections::{HashMap, VecDeque};
use std::io::Error as IOError;
@@ -97,6 +98,9 @@ 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>,

@@ -125,6 +129,15 @@ pub struct Constellation<Message, LTF, STF> {
/// A channel through which messages can be sent to the bluetooth thread.
bluetooth_thread: IpcSender<BluetoothMethodMsg>,

/// Sender to Service Worker Manager thread
swmanager_chan: Option<IpcSender<ServiceWorkerMsg>>,

/// to send messages to this object
swmanager_sender: IpcSender<SWManagerMsg>,

/// to receive sw manager message
swmanager_receiver: Receiver<SWManagerMsg>,

/// A list of all the pipelines. (See the `pipeline` module for more details.)
pipelines: HashMap<PipelineId, Pipeline>,

@@ -410,9 +423,13 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
where LTF: LayoutThreadFactory<Message=Message>,
STF: ScriptThreadFactory<Message=Message>
{
pub fn start(state: InitialConstellationState) -> Sender<FromCompositorMsg> {
pub fn start(state: InitialConstellationState) -> (Sender<FromCompositorMsg>, IpcSender<SWManagerMsg>) {
let (compositor_sender, compositor_receiver) = channel();

// service worker manager to communicate with constellation
let (swmanager_sender, swmanager_receiver) = ipc::channel().expect("ipc channel failure");
let sw_mgr_clone = swmanager_sender.clone();

spawn_named("Constellation".to_owned(), move || {
let (ipc_script_sender, ipc_script_receiver) = ipc::channel().expect("ipc channel failure");
let script_receiver = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_script_receiver);
@@ -423,6 +440,15 @@ 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 {
script_sender: ipc_script_sender,
layout_sender: ipc_layout_sender,
@@ -438,6 +464,10 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
private_resource_threads: state.private_resource_threads,
image_cache_thread: state.image_cache_thread,
font_cache_thread: state.font_cache_thread,
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(),
@@ -482,7 +512,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
PipelineNamespace::install(namespace_id);
constellation.run();
});
compositor_sender
(compositor_sender, swmanager_sender)
}

fn run(&mut self) {
@@ -534,6 +564,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
compositor_proxy: self.compositor_proxy.clone_compositor_proxy(),
devtools_chan: self.devtools_chan.clone(),
bluetooth_thread: self.bluetooth_thread.clone(),
swmanager_thread: self.swmanager_sender.clone(),
image_cache_thread: self.image_cache_thread.clone(),
font_cache_thread: self.font_cache_thread.clone(),
resource_threads: resource_threads,
@@ -607,6 +638,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
Compositor(FromCompositorMsg),
Layout(FromLayoutMsg),
Panic(PanicMsg),
FromSWManager(SWManagerMsg),
FromResource(CustomResponseMediator),
}

// Get one incoming request.
@@ -625,6 +658,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
let receiver_from_compositor = &self.compositor_receiver;
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")),
@@ -633,7 +668,11 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
msg = receiver_from_layout.recv() =>
Request::Layout(msg.expect("Unexpected layout channel panic in constellation")),
msg = receiver_from_panic.recv() =>
Request::Panic(msg.expect("Unexpected panic channel panic in constellation"))
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"))
}
};

@@ -650,6 +689,29 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
Request::Panic(message) => {
self.handle_request_from_panic(message);
},
Request::FromSWManager(message) => {
self.handle_request_from_swmanager(message);
}
Request::FromResource(message) => {
self.handle_request_from_resource(message);
}
}
}

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);
}
}
}

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");
}
}

@@ -923,6 +985,14 @@ 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);
}
}
}

@@ -950,6 +1020,22 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
}

fn handle_register_serviceworker(&self, scope_things: ScopeThings, scope: Url) {
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");
}
}

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; }
@@ -999,6 +1085,13 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
warn!("Exit bluetooth thread failed ({})", e);
}

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

debug!("Exiting font cache thread.");
self.font_cache_thread.exit();

@@ -25,7 +25,7 @@ use net_traits::image_cache_thread::ImageCacheThread;
use profile_traits::mem as profile_mem;
use profile_traits::time;
use script_traits::{ConstellationControlMsg, InitialScriptState, MozBrowserEvent};
use script_traits::{LayoutControlMsg, LayoutMsg, NewLayoutInfo, ScriptMsg};
use script_traits::{LayoutControlMsg, LayoutMsg, NewLayoutInfo, ScriptMsg, SWManagerMsg};
use script_traits::{ScriptThreadFactory, TimerEventRequest, WindowSizeData};
use std::collections::HashMap;
use std::io::Error as IOError;
@@ -99,6 +99,8 @@ pub struct InitialPipelineState {
pub devtools_chan: Option<Sender<DevtoolsControlMsg>>,
/// A channel to the bluetooth thread.
pub bluetooth_thread: IpcSender<BluetoothMethodMsg>,
/// A channel to the service worker manager thread
pub swmanager_thread: IpcSender<SWManagerMsg>,
/// A channel to the image cache thread.
pub image_cache_thread: ImageCacheThread,
/// A channel to the font cache thread.
@@ -222,6 +224,7 @@ impl Pipeline {
scheduler_chan: state.scheduler_chan,
devtools_chan: script_to_devtools_chan,
bluetooth_thread: state.bluetooth_thread,
swmanager_thread: state.swmanager_thread,
image_cache_thread: state.image_cache_thread,
font_cache_thread: state.font_cache_thread,
resource_threads: state.resource_threads,
@@ -414,6 +417,7 @@ pub struct UnprivilegedPipelineContent {
scheduler_chan: IpcSender<TimerEventRequest>,
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
bluetooth_thread: IpcSender<BluetoothMethodMsg>,
swmanager_thread: IpcSender<SWManagerMsg>,
image_cache_thread: ImageCacheThread,
font_cache_thread: FontCacheThread,
resource_threads: ResourceThreads,
@@ -546,4 +550,8 @@ impl UnprivilegedPipelineContent {
pub fn prefs(&self) -> HashMap<String, Pref> {
self.prefs.clone()
}

pub fn swmanager_chan(&self) -> IpcSender<SWManagerMsg> {
self.swmanager_thread.clone()
}
}
@@ -6,7 +6,7 @@ use font_template::{FontTemplate, FontTemplateDescriptor};
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use ipc_channel::router::ROUTER;
use mime::{TopLevel, SubLevel};
use net_traits::{AsyncResponseTarget, LoadContext, PendingAsyncLoad, CoreResourceThread, ResponseAction, RequestSource};
use net_traits::{AsyncResponseTarget, LoadContext, PendingAsyncLoad, CoreResourceThread, ResponseAction};
use platform::font_context::FontContextHandle;
use platform::font_list::SANS_SERIF_FONT_FAMILY;
use platform::font_list::for_each_available_family;
@@ -211,8 +211,7 @@ impl FontCache {
url.clone(),
None,
None,
None,
RequestSource::None);
None);
let (data_sender, data_receiver) = ipc::channel().unwrap();
let data_target = AsyncResponseTarget {
sender: data_sender,
@@ -7,7 +7,7 @@ use mime_classifier::MimeClassifier;
use mime_guess::guess_mime_type;
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
use net_traits::ProgressMsg::{Done, Payload};
use net_traits::{LoadConsumer, LoadData, Metadata, NetworkError, LoadOrigin, RequestSource};
use net_traits::{LoadConsumer, LoadData, Metadata, NetworkError, LoadOrigin};
use resource_thread::{CancellationListener, ProgressSender};
use resource_thread::{send_error, start_sending_sniffed_opt};
use std::borrow::ToOwned;
@@ -39,9 +39,6 @@ impl LoadOrigin for FileLoadOrigin {
fn referrer_policy(&self) -> Option<ReferrerPolicy> {
None
}
fn request_source(&self) -> RequestSource {
RequestSource::None
}
fn pipeline_id(&self) -> Option<PipelineId> {
None
}
@@ -24,15 +24,15 @@ use hyper::method::Method;
use hyper::mime::{Mime, SubLevel, TopLevel};
use hyper::net::Fresh;
use hyper::status::{StatusClass, StatusCode};
use ipc_channel::ipc;
use ipc_channel::ipc::{self, IpcSender};
use log;
use mime_classifier::MimeClassifier;
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
use net_traits::ProgressMsg::{Done, Payload};
use net_traits::hosts::replace_hosts;
use net_traits::response::HttpsState;
use net_traits::{CookieSource, IncludeSubdomains, LoadConsumer, LoadContext, LoadData};
use net_traits::{Metadata, NetworkError, RequestSource, CustomResponse};
use net_traits::{Metadata, NetworkError, CustomResponse, CustomResponseMediator};
use openssl;
use openssl::ssl::error::{SslError, OpensslError};
use profile_traits::time::{ProfilerCategory, profile, ProfilerChan, TimerMetadata};
@@ -59,6 +59,7 @@ pub fn factory(user_agent: String,
http_state: HttpState,
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
profiler_chan: ProfilerChan,
constellation_chan: Option<IpcSender<CustomResponseMediator>>,
connector: Arc<Pool<Connector>>)
-> Box<FnBox(LoadData,
LoadConsumer,
@@ -78,6 +79,7 @@ pub fn factory(user_agent: String,
connector,
http_state,
devtools_chan,
constellation_chan,
cancel_listener,
user_agent)
})
@@ -131,6 +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>>,
cancel_listener: CancellationListener,
user_agent: String) {
let factory = NetworkHttpRequestFactory {
@@ -140,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) {
user_agent, &cancel_listener, constellation_chan) {
Err(error) => {
match error.error {
LoadErrorType::ConnectionAborted { .. } => unreachable!(),
@@ -860,7 +863,8 @@ pub fn load<A, B>(load_data: &LoadData,
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
request_factory: &HttpRequestFactory<R=A>,
user_agent: String,
cancel_listener: &CancellationListener)
cancel_listener: &CancellationListener,
constellation_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;
@@ -878,17 +882,19 @@ pub fn load<A, B>(load_data: &LoadData,
}

let (msg_sender, msg_receiver) = ipc::channel().unwrap();
match load_data.source {
RequestSource::Window(ref sender) | RequestSource::Worker(ref sender) => {
sender.send(msg_sender.clone()).unwrap();
let received_msg = msg_receiver.recv().unwrap();
if let Some(custom_response) = received_msg {
let metadata = Metadata::default(doc_url.clone());
let readable_response = to_readable_response(custom_response);
return StreamedResponse::from_http_response(box readable_response, metadata);
}
let response_mediator = CustomResponseMediator {
response_chan: msg_sender,
load_url: doc_url.clone()
};
if let Some(sender) = constellation_chan {
let _ = sender.send(response_mediator);
if let Ok(Some(custom_response)) = msg_receiver.try_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);
}
RequestSource::None => {}
} else {
debug!("Did not receive a custom response");
}

// If the URL is a view-source scheme then the scheme data contains the
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.