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

Close the correct pipelines when evicted from navigation context. #966

Merged
merged 4 commits into from Sep 24, 2013
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Prev

split script_task::ExitMsg into WindowExitMsg and PipelineExitMsg

  • Loading branch information
Tim Kuehn
Tim Kuehn committed Sep 24, 2013
commit 103cd6255d03f22fb8cc931a160d8601644cc35f
@@ -760,6 +760,28 @@ impl Constellation {
}
}

// Close all pipelines at and beneath a given frame
fn close_pipelines(&mut self, frame_tree: @mut FrameTree) {
// TODO(tkuehn): should only exit once per unique script task,
// and then that script task will handle sub-exits
for @FrameTree { pipeline, _ } in frame_tree.iter() {
pipeline.exit();
self.pipelines.remove(&pipeline.id);
}
}

fn handle_evicted_frames(&mut self, evicted: ~[@mut FrameTree]) {
for &frame_tree in evicted.iter() {
if !self.navigation_context.contains(frame_tree.pipeline.id) {
self.close_pipelines(frame_tree);
} else {
self.handle_evicted_frames(frame_tree.children.iter()
.map(|child| child.frame_tree)
.collect());
}
}
}

// Grants a frame tree permission to paint; optionally updates navigation to reflect a new page
fn grant_paint_permission(&mut self, frame_tree: @mut FrameTree, navigation_type: NavigationType) {
// Give permission to paint to the new frame and all child frames
@@ -770,20 +792,7 @@ impl Constellation {
match navigation_type {
constellation_msg::Load => {
let evicted = self.navigation_context.load(frame_tree);
let mut exited = HashSet::new();
// exit any pipelines that don't exist outside the evicted frame trees
for frame_tree in evicted.iter() {
for @FrameTree { pipeline, _ } in frame_tree.iter() {
if !self.navigation_context.contains(pipeline.id) &&
!exited.contains(&pipeline.id) {
debug!("Constellation: shutting down pipeline %?", pipeline.id);
pipeline.exit();
self.pipelines.remove(&pipeline.id);

exited.insert(pipeline.id);
}
}
}
self.handle_evicted_frames(evicted);
}
_ => {}
}
@@ -26,6 +26,7 @@ use gfx::font_context::FontContext;
use gfx::geometry::Au;
use gfx::opts::Opts;
use gfx::render_task::{RenderMsg, RenderChan, RenderLayer};
use gfx::render_task;
use newcss::select::SelectCtx;
use newcss::stylesheet::Stylesheet;
use newcss::types::OriginAuthor;
@@ -162,6 +163,9 @@ impl LayoutTask {
}
ExitMsg => {
debug!("layout: ExitMsg received");
let (response_port, response_chan) = stream();
self.render_chan.send(render_task::ExitMsg(response_chan));
response_port.recv();
return false
}
}
@@ -5,7 +5,7 @@
macro_rules! special_stream(
($Chan:ident) => (
{
let (port, chan) = comm::stream::();
let (port, chan) = stream::();
(port, $Chan::new(chan))
}
);
@@ -6,7 +6,6 @@ use extra::url::Url;
use compositing::CompositorChan;
use gfx::render_task::{RenderChan, RenderTask};
use gfx::render_task::{PaintPermissionGranted, PaintPermissionRevoked};
use gfx::render_task;
use gfx::opts::Opts;
use layout::layout_task::LayoutTask;
use script::layout_interface::LayoutChan;
@@ -21,7 +20,6 @@ use servo_util::time::ProfilerChan;
use geom::size::Size2D;
use extra::future::Future;
use std::cell::Cell;
use std::comm;
use std::task;

/// A uniquely-identifiable pipeline of script task, layout task, and render task.
@@ -216,12 +214,9 @@ impl Pipeline {
}

pub fn exit(&self) {
// Script task handles shutting down layout, as well
self.script_chan.send(script_task::ExitMsg(self.id));

let (response_port, response_chan) = comm::stream();
self.render_chan.send(render_task::ExitMsg(response_chan));
response_port.recv();
// Script task handles shutting down layout,
// and layout handles shutting down the renderer.
self.script_chan.try_send(script_task::ExitPipelineMsg(self.id));
}
}

@@ -10,7 +10,7 @@ use dom::node::{AbstractNode, ScriptView};
use dom::navigator::Navigator;

use layout_interface::ReflowForDisplay;
use script_task::{ExitMsg, FireTimerMsg, Page, ScriptChan};
use script_task::{ExitWindowMsg, FireTimerMsg, Page, ScriptChan};
use servo_msg::compositor_msg::ScriptListener;
use servo_net::image_cache_task::ImageCacheTask;

@@ -212,7 +212,7 @@ impl Window {
match timer_port.recv() {
TimerMessage_Close => break,
TimerMessage_Fire(td) => script_chan.send(FireTimerMsg(id, td)),
TimerMessage_TriggerExit => script_chan.send(ExitMsg(id)),
TimerMessage_TriggerExit => script_chan.send(ExitWindowMsg(id)),
}
}
}
@@ -70,8 +70,10 @@ pub enum ScriptMsg {
ReflowCompleteMsg(PipelineId, uint),
/// Notifies script that window has been resized but to not take immediate action.
ResizeInactiveMsg(PipelineId, Size2D<uint>),
/// Exits the constellation.
ExitMsg(PipelineId),
/// Notifies the script that a pipeline should be closed.
ExitPipelineMsg(PipelineId),
/// Notifies the script that a window associated with a particular pipeline should be closed.
ExitWindowMsg(PipelineId),
}

pub struct NewLayoutInfo {
@@ -516,9 +518,8 @@ impl ScriptTask {
NavigateMsg(direction) => self.handle_navigate_msg(direction),
ReflowCompleteMsg(id, reflow_id) => self.handle_reflow_complete_msg(id, reflow_id),
ResizeInactiveMsg(id, new_size) => self.handle_resize_inactive_msg(id, new_size),
ExitMsg(id) => {
if self.handle_exit_msg(id) { return false }
},
ExitPipelineMsg(id) => if self.handle_exit_pipeline_msg(id) { return false },
ExitWindowMsg(id) => if self.handle_exit_window_msg(id) { return false },
ResizeMsg(*) => fail!("should have handled ResizeMsg already"),
}
}
@@ -623,9 +624,17 @@ impl ScriptTask {
}
}

fn handle_exit_window_msg(&mut self, _id: PipelineId) -> bool {
// TODO(tkuehn): currently there is only one window,
// so this can afford to be naive and just shut down the
// compositor. In the future it'll need to be smarter.
self.compositor.close();
true
}

/// Handles a request to exit the script task and shut down layout.
/// Returns true if the script task should shut down and false otherwise.
fn handle_exit_msg(&mut self, id: PipelineId) -> bool {
fn handle_exit_pipeline_msg(&mut self, id: PipelineId) -> bool {
// If root is being exited, shut down all pages
if self.page_tree.page.id == id {
for page in self.page_tree.iter() {
@@ -641,10 +650,12 @@ impl ScriptTask {
page.join_layout();
page.layout_chan.send(layout_interface::ExitMsg);
}
return false
false
}
None => fail!("ScriptTask: Received exit message from
pipeline whose id is not in page tree"),
// TODO(tkuehn): pipeline closing is currently duplicated across
// script and constellation, which can cause this to happen. Constellation
// needs to be smarter about exiting pipelines.
None => false,
}

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