make use of ScriptToConstellationChan

This commit is contained in:
Paul Rouget 2017-07-18 08:19:44 +02:00
parent 817de15735
commit d241389129
24 changed files with 285 additions and 280 deletions

View file

@ -105,7 +105,7 @@ use script_traits::{ConstellationControlMsg, ConstellationMsg as FromCompositorM
use script_traits::{DocumentActivity, DocumentState, LayoutControlMsg, LoadData};
use script_traits::{IFrameLoadInfo, IFrameLoadInfoWithData, IFrameSandboxState, TimerSchedulerMsg};
use script_traits::{LayoutMsg as FromLayoutMsg, ScriptMsg as FromScriptMsg, ScriptThreadFactory};
use script_traits::{LogEntry, ServiceWorkerMsg, webdriver_msg};
use script_traits::{LogEntry, ScriptToConstellationChan, ServiceWorkerMsg, webdriver_msg};
use script_traits::{MozBrowserErrorType, MozBrowserEvent, WebDriverCommandMsg, WindowSizeData};
use script_traits::{SWManagerMsg, ScopeThings, UpdatePipelineIdReason, WindowSizeType};
use serde::{Deserialize, Serialize};
@ -147,11 +147,11 @@ use webvr_traits::{WebVREvent, WebVRMsg};
pub struct Constellation<Message, LTF, STF> {
/// An IPC channel for script threads to send messages to the constellation.
/// This is the script threads' view of `script_receiver`.
script_sender: IpcSender<FromScriptMsg>,
script_sender: IpcSender<(PipelineId, FromScriptMsg)>,
/// A channel for the constellation to receive messages from script threads.
/// This is the constellation's view of `script_sender`.
script_receiver: Receiver<Result<FromScriptMsg, IpcError>>,
script_receiver: Receiver<Result<(PipelineId, FromScriptMsg), IpcError>>,
/// An IPC channel for layout threads to send messages to the constellation.
/// This is the layout threads' view of `layout_receiver`.
@ -385,14 +385,14 @@ enum ExitPipelineMode {
#[derive(Clone)]
pub struct FromScriptLogger {
/// A channel to the constellation
pub constellation_chan: Arc<ReentrantMutex<IpcSender<FromScriptMsg>>>,
pub script_to_constellation_chan: Arc<ReentrantMutex<ScriptToConstellationChan>>,
}
impl FromScriptLogger {
/// Create a new constellation logger.
pub fn new(constellation_chan: IpcSender<FromScriptMsg>) -> FromScriptLogger {
pub fn new(script_to_constellation_chan: ScriptToConstellationChan) -> FromScriptLogger {
FromScriptLogger {
constellation_chan: Arc::new(ReentrantMutex::new(constellation_chan))
script_to_constellation_chan: Arc::new(ReentrantMutex::new(script_to_constellation_chan))
}
}
@ -410,10 +410,9 @@ impl Log for FromScriptLogger {
fn log(&self, record: &LogRecord) {
if let Some(entry) = log_entry(record) {
debug!("Sending log entry {:?}.", entry);
let top_level_id = TopLevelBrowsingContextId::installed();
let thread_name = thread::current().name().map(ToOwned::to_owned);
let msg = FromScriptMsg::LogEntry(top_level_id, thread_name, entry);
let chan = self.constellation_chan.lock().unwrap_or_else(|err| err.into_inner());
let msg = FromScriptMsg::LogEntry(thread_name, entry);
let chan = self.script_to_constellation_chan.lock().unwrap_or_else(|err| err.into_inner());
let _ = chan.send(msg);
}
}
@ -674,7 +673,10 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
browsing_context_id,
top_level_browsing_context_id,
parent_info,
constellation_chan: self.script_sender.clone(),
script_to_constellation_chan: ScriptToConstellationChan {
sender: self.script_sender.clone(),
pipeline_id: pipeline_id,
},
layout_to_constellation_chan: self.layout_sender.clone(),
scheduler_chan: self.scheduler_chan.clone(),
compositor_proxy: self.compositor_proxy.clone_compositor_proxy(),
@ -816,7 +818,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
#[allow(unsafe_code)]
fn handle_request(&mut self) {
enum Request {
Script(FromScriptMsg),
Script((PipelineId, FromScriptMsg)),
Compositor(FromCompositorMsg),
Layout(FromLayoutMsg),
NetworkListener((PipelineId, FetchResponseMsg)),
@ -995,14 +997,26 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
}
fn handle_request_from_script(&mut self, message: FromScriptMsg) {
match message {
FromScriptMsg::PipelineExited(pipeline_id) => {
self.handle_pipeline_exited(pipeline_id);
fn handle_request_from_script(&mut self, message: (PipelineId, FromScriptMsg)) {
let (source_pipeline_id, content) = message;
let source_top_ctx_id = match self.pipelines.get(&source_pipeline_id)
.map(|pipeline| pipeline.top_level_browsing_context_id) {
None => return warn!("ScriptMsg from closed pipeline {:?}.", source_pipeline_id),
Some(ctx) => ctx,
};
let source_is_top_level_pipeline = self.browsing_contexts
.get(&BrowsingContextId::from(source_top_ctx_id))
.map(|ctx| ctx.pipeline_id == source_pipeline_id)
.unwrap_or(false);
match content {
FromScriptMsg::PipelineExited => {
self.handle_pipeline_exited(source_pipeline_id);
}
FromScriptMsg::InitiateNavigateRequest(req_init, pipeline_id) => {
FromScriptMsg::InitiateNavigateRequest(req_init) => {
debug!("constellation got initiate navigate request message");
self.handle_navigate_request(req_init, pipeline_id);
self.handle_navigate_request(source_pipeline_id, req_init);
}
FromScriptMsg::ScriptLoadedURLInIFrame(load_info) => {
debug!("constellation got iframe URL load message {:?} {:?} {:?}",
@ -1017,40 +1031,40 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
load_info.new_pipeline_id);
self.handle_script_new_iframe(load_info, layout_sender);
}
FromScriptMsg::ChangeRunningAnimationsState(pipeline_id, animation_state) => {
self.handle_change_running_animations_state(pipeline_id, animation_state)
FromScriptMsg::ChangeRunningAnimationsState(animation_state) => {
self.handle_change_running_animations_state(source_pipeline_id, animation_state)
}
// Load a new page from a mouse click
// If there is already a pending page (self.pending_changes), it will not be overridden;
// However, if the id is not encompassed by another change, it will be.
FromScriptMsg::LoadUrl(source_id, load_data, replace) => {
FromScriptMsg::LoadUrl(load_data, replace) => {
debug!("constellation got URL load message from script");
self.handle_load_url_msg(source_id, load_data, replace);
self.handle_load_url_msg(source_top_ctx_id, source_pipeline_id, load_data, replace);
}
// A page loaded has completed all parsing, script, and reflow messages have been sent.
FromScriptMsg::LoadComplete(pipeline_id) => {
FromScriptMsg::LoadComplete => {
debug!("constellation got load complete message");
self.handle_load_complete_msg(pipeline_id)
self.handle_load_complete_msg(source_top_ctx_id, source_pipeline_id)
}
// Handle a forward or back request
FromScriptMsg::TraverseHistory(top_level_browsing_context_id, direction) => {
FromScriptMsg::TraverseHistory(direction) => {
debug!("constellation got traverse history message from script");
self.handle_traverse_history_msg(top_level_browsing_context_id, direction);
self.handle_traverse_history_msg(source_top_ctx_id, direction);
}
// Handle a joint session history length request.
FromScriptMsg::JointSessionHistoryLength(top_level_browsing_context_id, sender) => {
FromScriptMsg::JointSessionHistoryLength(sender) => {
debug!("constellation got joint session history length message from script");
self.handle_joint_session_history_length(top_level_browsing_context_id, sender);
self.handle_joint_session_history_length(source_top_ctx_id, sender);
}
// Notification that the new document is ready to become active
FromScriptMsg::ActivateDocument(pipeline_id) => {
FromScriptMsg::ActivateDocument => {
debug!("constellation got activate document message");
self.handle_activate_document_msg(pipeline_id);
self.handle_activate_document_msg(source_pipeline_id);
}
// Update pipeline url after redirections
FromScriptMsg::SetFinalUrl(pipeline_id, final_url) => {
FromScriptMsg::SetFinalUrl(final_url) => {
// The script may have finished loading after we already started shutting down.
if let Some(ref mut pipeline) = self.pipelines.get_mut(&pipeline_id) {
if let Some(ref mut pipeline) = self.pipelines.get_mut(&source_pipeline_id) {
debug!("constellation got set final url message");
pipeline.url = final_url;
} else {
@ -1061,22 +1075,22 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
debug!("constellation got postMessage message");
self.handle_post_message_msg(browsing_context_id, origin, data);
}
FromScriptMsg::MozBrowserEvent(pipeline_id, top_level_browsing_context_id, event) => {
FromScriptMsg::MozBrowserEvent(pipeline_id, event) => {
debug!("constellation got mozbrowser event message");
self.handle_mozbrowser_event_msg(pipeline_id, top_level_browsing_context_id, event);
self.handle_mozbrowser_event_msg(pipeline_id, source_top_ctx_id, event);
}
FromScriptMsg::Focus(pipeline_id) => {
FromScriptMsg::Focus => {
debug!("constellation got focus message");
self.handle_focus_msg(pipeline_id);
self.handle_focus_msg(source_pipeline_id);
}
FromScriptMsg::ForwardEvent(pipeline_id, event) => {
let msg = ConstellationControlMsg::SendEvent(pipeline_id, event);
let result = match self.pipelines.get(&pipeline_id) {
None => { debug!("Pipeline {:?} got event after closure.", pipeline_id); return; }
FromScriptMsg::ForwardEvent(dest_id, event) => {
let msg = ConstellationControlMsg::SendEvent(dest_id, event);
let result = match self.pipelines.get(&dest_id) {
None => { debug!("Pipeline {:?} got event after closure.", dest_id); return; }
Some(pipeline) => pipeline.event_loop.send(msg),
};
if let Err(e) = result {
self.handle_send_error(pipeline_id, e);
self.handle_send_error(dest_id, e);
}
}
FromScriptMsg::GetClipboardContents(sender) => {
@ -1101,13 +1115,13 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
}
}
FromScriptMsg::SetVisible(pipeline_id, visible) => {
FromScriptMsg::SetVisible(visible) => {
debug!("constellation got set visible messsage");
self.handle_set_visible_msg(pipeline_id, visible);
self.handle_set_visible_msg(source_pipeline_id, visible);
}
FromScriptMsg::VisibilityChangeComplete(pipeline_id, visible) => {
FromScriptMsg::VisibilityChangeComplete(visible) => {
debug!("constellation got set visibility change complete message");
self.handle_visibility_change_complete(pipeline_id, visible);
self.handle_visibility_change_complete(source_pipeline_id, visible);
}
FromScriptMsg::RemoveIFrame(browsing_context_id, sender) => {
debug!("constellation got remove iframe message");
@ -1118,11 +1132,15 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
FromScriptMsg::NewFavicon(url) => {
debug!("constellation got new favicon message");
self.compositor_proxy.send(ToCompositorMsg::NewFavicon(url));
if source_is_top_level_pipeline {
self.compositor_proxy.send(ToCompositorMsg::NewFavicon(source_top_ctx_id, url));
}
}
FromScriptMsg::HeadParsed => {
debug!("constellation got head parsed message");
self.compositor_proxy.send(ToCompositorMsg::HeadParsed);
if source_is_top_level_pipeline {
self.compositor_proxy.send(ToCompositorMsg::HeadParsed(source_top_ctx_id));
}
}
FromScriptMsg::CreateCanvasPaintThread(size, sender) => {
debug!("constellation got create-canvas-paint-thread message");
@ -1134,15 +1152,15 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
FromScriptMsg::NodeStatus(message) => {
debug!("constellation got NodeStatus message");
self.compositor_proxy.send(ToCompositorMsg::Status(message));
self.compositor_proxy.send(ToCompositorMsg::Status(source_top_ctx_id, message));
}
FromScriptMsg::SetDocumentState(pipeline_id, state) => {
FromScriptMsg::SetDocumentState(state) => {
debug!("constellation got SetDocumentState message");
self.document_states.insert(pipeline_id, state);
self.document_states.insert(source_pipeline_id, state);
}
FromScriptMsg::Alert(pipeline_id, message, sender) => {
FromScriptMsg::Alert(message, sender) => {
debug!("constellation got Alert message");
self.handle_alert(pipeline_id, message, sender);
self.handle_alert(source_top_ctx_id, message, sender);
}
FromScriptMsg::ScrollFragmentPoint(scroll_root_id, point, smooth) => {
@ -1152,30 +1170,33 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
FromScriptMsg::GetClientWindow(send) => {
self.compositor_proxy.send(ToCompositorMsg::GetClientWindow(send));
self.compositor_proxy.send(ToCompositorMsg::GetClientWindow(source_top_ctx_id, send));
}
FromScriptMsg::MoveTo(point) => {
self.compositor_proxy.send(ToCompositorMsg::MoveTo(point));
self.compositor_proxy.send(ToCompositorMsg::MoveTo(source_top_ctx_id, point));
}
FromScriptMsg::ResizeTo(size) => {
self.compositor_proxy.send(ToCompositorMsg::ResizeTo(size));
self.compositor_proxy.send(ToCompositorMsg::ResizeTo(source_top_ctx_id, size));
}
FromScriptMsg::Exit => {
self.compositor_proxy.send(ToCompositorMsg::Exit);
}
FromScriptMsg::LogEntry(top_level_browsing_context_id, thread_name, entry) => {
self.handle_log_entry(top_level_browsing_context_id, thread_name, entry);
FromScriptMsg::LogEntry(thread_name, entry) => {
self.handle_log_entry(Some(source_top_ctx_id), thread_name, entry);
}
FromScriptMsg::SetTitle(pipeline_id, title) => {
self.compositor_proxy.send(ToCompositorMsg::ChangePageTitle(pipeline_id, title))
FromScriptMsg::SetTitle(title) => {
if source_is_top_level_pipeline {
self.compositor_proxy.send(ToCompositorMsg::ChangePageTitle(source_top_ctx_id, title))
}
}
FromScriptMsg::SendKeyEvent(ch, key, key_state, key_modifiers) => {
self.compositor_proxy.send(ToCompositorMsg::KeyEvent(ch, key, key_state, key_modifiers))
let event = ToCompositorMsg::KeyEvent(Some(source_top_ctx_id), ch, key, key_state, key_modifiers);
self.compositor_proxy.send(event);
}
FromScriptMsg::TouchEventProcessed(result) => {
@ -1204,11 +1225,11 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
warn!("Unable to forward DOMMessage for postMessage call");
}
}
FromScriptMsg::BroadcastStorageEvent(pipeline_id, storage, url, key, old_value, new_value) => {
self.handle_broadcast_storage_event(pipeline_id, storage, url, key, old_value, new_value);
FromScriptMsg::BroadcastStorageEvent(storage, url, key, old_value, new_value) => {
self.handle_broadcast_storage_event(source_pipeline_id, storage, url, key, old_value, new_value);
}
FromScriptMsg::SetFullscreenState(state) => {
self.compositor_proxy.send(ToCompositorMsg::SetFullscreenState(state));
self.compositor_proxy.send(ToCompositorMsg::SetFullscreenState(source_top_ctx_id, state));
}
}
}
@ -1539,8 +1560,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
fn handle_navigate_request(&self,
req_init: RequestInit,
id: PipelineId) {
id: PipelineId,
req_init: RequestInit) {
let listener = NetworkListener::new(
req_init,
id,
@ -1698,14 +1719,10 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
fn handle_alert(&mut self,
pipeline_id: PipelineId,
top_level_browsing_context_id: TopLevelBrowsingContextId,
message: String,
sender: IpcSender<bool>) {
let top_level_browsing_context_id = self.pipelines.get(&pipeline_id)
.map(|pipeline| pipeline.top_level_browsing_context_id);
let browser_pipeline_id = top_level_browsing_context_id
.map(BrowsingContextId::from)
.and_then(|browsing_context_id| self.browsing_contexts.get(&browsing_context_id))
let browser_pipeline_id = self.browsing_contexts.get(&BrowsingContextId::from(top_level_browsing_context_id))
.and_then(|browsing_context| self.pipelines.get(&browsing_context.pipeline_id))
.and_then(|pipeline| pipeline.parent_info)
.map(|(browser_pipeline_id, _)| browser_pipeline_id);
@ -1719,12 +1736,17 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
let event = MozBrowserEvent::ShowModalPrompt(prompt_type, title, message, return_value);
match browser_pipeline_id.and_then(|id| self.pipelines.get(&id)) {
None => warn!("Alert sent after browser pipeline closure."),
Some(pipeline) => pipeline.trigger_mozbrowser_event(top_level_browsing_context_id, event),
Some(pipeline) => pipeline.trigger_mozbrowser_event(Some(top_level_browsing_context_id), event),
}
}
let result = sender.send(!mozbrowser_modal_prompt);
if let Err(e) = result {
let ctx_id = BrowsingContextId::from(top_level_browsing_context_id);
let pipeline_id = match self.browsing_contexts.get(&ctx_id) {
Some(ctx) => ctx.pipeline_id,
None => return warn!("Alert sent for unknown browsing context."),
};
self.handle_send_error(pipeline_id, e);
}
}

View file

@ -21,10 +21,10 @@ use net_traits::{IpcSend, ResourceThreads};
use net_traits::image_cache::ImageCache;
use profile_traits::mem as profile_mem;
use profile_traits::time;
use script_traits::{ConstellationControlMsg, DiscardBrowsingContext};
use script_traits::{ConstellationControlMsg, DiscardBrowsingContext, ScriptToConstellationChan};
use script_traits::{DocumentActivity, InitialScriptState};
use script_traits::{LayoutControlMsg, LayoutMsg, LoadData, MozBrowserEvent};
use script_traits::{NewLayoutInfo, SWManagerMsg, SWManagerSenders, ScriptMsg};
use script_traits::{NewLayoutInfo, SWManagerMsg, SWManagerSenders};
use script_traits::{ScriptThreadFactory, TimerSchedulerMsg, WindowSizeData};
use servo_config::opts::{self, Opts};
use servo_config::prefs::{PREFS, Pref};
@ -112,7 +112,7 @@ pub struct InitialPipelineState {
pub parent_info: Option<(PipelineId, FrameType)>,
/// A channel to the associated constellation.
pub constellation_chan: IpcSender<ScriptMsg>,
pub script_to_constellation_chan: ScriptToConstellationChan,
/// A channel for the layout thread to send messages to the constellation.
pub layout_to_constellation_chan: IpcSender<LayoutMsg>,
@ -246,7 +246,7 @@ impl Pipeline {
browsing_context_id: state.browsing_context_id,
top_level_browsing_context_id: state.top_level_browsing_context_id,
parent_info: state.parent_info,
constellation_chan: state.constellation_chan,
script_to_constellation_chan: state.script_to_constellation_chan.clone(),
scheduler_chan: state.scheduler_chan,
devtools_chan: script_to_devtools_chan,
bluetooth_thread: state.bluetooth_thread,
@ -446,7 +446,7 @@ pub struct UnprivilegedPipelineContent {
top_level_browsing_context_id: TopLevelBrowsingContextId,
browsing_context_id: BrowsingContextId,
parent_info: Option<(PipelineId, FrameType)>,
constellation_chan: IpcSender<ScriptMsg>,
script_to_constellation_chan: ScriptToConstellationChan,
layout_to_constellation_chan: IpcSender<LayoutMsg>,
scheduler_chan: IpcSender<TimerSchedulerMsg>,
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
@ -487,7 +487,7 @@ impl UnprivilegedPipelineContent {
parent_info: self.parent_info,
control_chan: self.script_chan.clone(),
control_port: self.script_port,
constellation_chan: self.constellation_chan,
script_to_constellation_chan: self.script_to_constellation_chan.clone(),
layout_to_constellation_chan: self.layout_to_constellation_chan.clone(),
scheduler_chan: self.scheduler_chan,
bluetooth_thread: self.bluetooth_thread,
@ -595,8 +595,8 @@ impl UnprivilegedPipelineContent {
}
}
pub fn constellation_chan(&self) -> IpcSender<ScriptMsg> {
self.constellation_chan.clone()
pub fn script_to_constellation_chan(&self) -> &ScriptToConstellationChan {
&self.script_to_constellation_chan
}
pub fn opts(&self) -> Opts {