Skip to content

Commit

Permalink
Pipeline create is now wrapped in a task that supervises the tasks
Browse files Browse the repository at this point in the history
created by script, rendering, and layout. When any of those fail,
the pipeline is removed from the FrameTree and a new one is created
with a failure HTML file.

Additionally, the top-level Makefile is changed to store debug info.
  • Loading branch information
larsbergstrom committed Sep 12, 2013
1 parent 4cf80cd commit 26ec022
Show file tree
Hide file tree
Showing 10 changed files with 167 additions and 35 deletions.
4 changes: 2 additions & 2 deletions Makefile.in
Expand Up @@ -32,7 +32,7 @@ MKFILE_DEPS := config.stamp $(call rwildcard,$(S)mk/,*)
# Enable debug!() etc even without configure --enable-debug
# The evaluation of these prints & their arguments is controlled
# at runtime by the environment variable RUST_LOG.
CFG_RUSTC_FLAGS += --cfg debug
CFG_RUSTC_FLAGS += --cfg debug -Z debug-info

ifdef CFG_DISABLE_OPTIMIZE
$(info cfg: disabling rustc optimization (CFG_DISABLE_OPTIMIZE))
Expand All @@ -43,7 +43,7 @@ endif

ifdef CFG_ENABLE_DEBUG
$(info cfg: enabling more debugging (CFG_ENABLE_DEBUG))
CFG_RUSTC_FLAGS +=
CFG_RUSTC_FLAGS +=
CFG_GCCISH_CFLAGS += -DRUST_DEBUG
else
CFG_GCCISH_CFLAGS += -DRUST_NDEBUG
Expand Down
9 changes: 8 additions & 1 deletion src/components/main/compositing/compositor_layer.rs
Expand Up @@ -486,7 +486,14 @@ impl CompositorLayer {
} else {
// ID does not match ours, so recurse on descendents (including hidden children).
self.children.mut_iter().map(|x| &mut x.child)
.any(|x| x.add_buffers(pipeline_id, cell.take(), epoch))
.any(|x| { let buffers = cell.take();
let result = x.add_buffers(pipeline_id, buffers.clone(), epoch);
if result {
result
} else {
cell.put_back(buffers);
result
}})
}
}

Expand Down
41 changes: 39 additions & 2 deletions src/components/main/constellation.rs
Expand Up @@ -13,8 +13,8 @@ use geom::size::Size2D;
use geom::rect::Rect;
use gfx::opts::Opts;
use pipeline::Pipeline;
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, FrameRectMsg, IFrameSandboxState};
use servo_msg::constellation_msg::{InitLoadUrlMsg, LoadIframeUrlMsg, LoadUrlMsg};
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, FailureMsg, FrameRectMsg};
use servo_msg::constellation_msg::{IFrameSandboxState, InitLoadUrlMsg, LoadIframeUrlMsg, LoadUrlMsg};
use servo_msg::constellation_msg::{Msg, NavigateMsg, NavigationType, IFrameUnsandboxed};
use servo_msg::constellation_msg::{PipelineId, RendererReadyMsg, ResizedWindowMsg, SubpageId};
use servo_msg::constellation_msg;
Expand All @@ -23,6 +23,7 @@ use servo_net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient};
use servo_net::resource_task::ResourceTask;
use servo_net::resource_task;
use servo_util::time::ProfilerChan;
use servo_util::url::make_url;
use std::hashmap::{HashMap, HashSet};
use std::util::replace;
use extra::url::Url;
Expand Down Expand Up @@ -319,6 +320,9 @@ impl Constellation {
self.handle_exit(sender);
return false;
}
FailureMsg(pipeline_id, subpage_id) => {
self.handle_failure_msg(pipeline_id, subpage_id);
}
// This should only be called once per constellation, and only by the browser
InitLoadUrlMsg(url) => {
self.handle_init_load(url);
Expand Down Expand Up @@ -363,6 +367,39 @@ impl Constellation {
sender.send(());
}

fn handle_failure_msg(&mut self, pipeline_id: PipelineId, subpage_id: Option<SubpageId>) {
let new_id = self.get_next_pipeline_id();
let pipeline = @mut Pipeline::create(new_id,
subpage_id,
self.chan.clone(),
self.compositor_chan.clone(),
self.image_cache_task.clone(),
self.resource_task.clone(),
self.profiler_chan.clone(),
self.opts.clone(),
{
let size = self.compositor_chan.get_size();
from_value(Size2D(size.width as uint, size.height as uint))
});
// FIXME(lbergstrom): this should be in/relative-to the servo binary
let failure = ~"../src/test/html/failure.html";
let url = make_url(failure, None);
pipeline.load(url);

let frame_trees: ~[@mut FrameTree] = {
let matching_navi_frames = self.navigation_context.find_all(pipeline_id);
let matching_pending_frames = do self.pending_frames.iter().filter_map |frame_change| {
frame_change.after.find_mut(pipeline_id)
};
matching_navi_frames.move_iter().chain(matching_pending_frames).collect()
};
for frame_tree in frame_trees.iter() {
frame_tree.pipeline = pipeline;
};

self.pipelines.insert(pipeline_id, pipeline);
}

fn handle_init_load(&mut self, url: Url) {
let pipeline = @mut Pipeline::create(self.get_next_pipeline_id(),
None,
Expand Down
106 changes: 76 additions & 30 deletions src/components/main/pipeline.rs
Expand Up @@ -11,7 +11,7 @@ use gfx::opts::Opts;
use layout::layout_task::LayoutTask;
use script::layout_interface::LayoutChan;
use script::script_task::{ExecuteMsg, LoadMsg};
use servo_msg::constellation_msg::{ConstellationChan, PipelineId, SubpageId};
use servo_msg::constellation_msg::{ConstellationChan, FailureMsg, PipelineId, SubpageId};
use script::dom::node::AbstractNode;
use script::script_task::{AttachLayoutMsg, NewLayoutInfo, ScriptTask, ScriptChan};
use script::script_task;
Expand All @@ -20,9 +20,11 @@ use servo_net::resource_task::ResourceTask;
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 stript task, layout task, and render task.
/// A uniquely-identifiable pipeline of script task, layout task, and render task.
#[deriving(Clone)]
pub struct Pipeline {
id: PipelineId,
Expand Down Expand Up @@ -94,37 +96,81 @@ impl Pipeline {
let (script_port, script_chan) = special_stream!(ScriptChan);
let (layout_port, layout_chan) = special_stream!(LayoutChan);
let (render_port, render_chan) = special_stream!(RenderChan);
let pipeline = Pipeline::new(id,
subpage_id,
script_chan.clone(),
layout_chan.clone(),
render_chan.clone());
let (port, chan) = stream::<task::TaskResult>();

let script_port = Cell::new(script_port);
let resource_task = Cell::new(resource_task);
let size = Cell::new(size);
let render_port = Cell::new(render_port);
let layout_port = Cell::new(layout_port);
let constellation_chan_handler = Cell::new(constellation_chan.clone());
let constellation_chan = Cell::new(constellation_chan);
let image_cache_task = Cell::new(image_cache_task);
let profiler_chan = Cell::new(profiler_chan);

do Pipeline::spawn(chan) {
let script_port = script_port.take();
let resource_task = resource_task.take();
let size = size.take();
let render_port = render_port.take();
let layout_port = layout_port.take();
let constellation_chan = constellation_chan.take();
let image_cache_task = image_cache_task.take();
let profiler_chan = profiler_chan.take();

ScriptTask::create(id,
compositor_chan.clone(),
layout_chan.clone(),
script_port,
script_chan.clone(),
constellation_chan.clone(),
resource_task,
image_cache_task.clone(),
size);

RenderTask::create(id,
render_port,
compositor_chan.clone(),
opts.clone(),
profiler_chan.clone());

LayoutTask::create(id,
layout_port,
constellation_chan,
script_chan.clone(),
render_chan.clone(),
image_cache_task,
opts.clone(),
profiler_chan);
};

ScriptTask::create(id,
compositor_chan.clone(),
layout_chan.clone(),
script_port,
script_chan.clone(),
constellation_chan.clone(),
resource_task,
image_cache_task.clone(),
size);

do spawn {
match port.recv() {
task::Success => (),
task::Failure => {
let constellation_chan = constellation_chan_handler.take();
constellation_chan.send(FailureMsg(id, subpage_id));
}
}
};

RenderTask::create(id,
render_port,
compositor_chan.clone(),
opts.clone(),
profiler_chan.clone());
pipeline
}

LayoutTask::create(id,
layout_port,
constellation_chan,
script_chan.clone(),
render_chan.clone(),
image_cache_task,
opts.clone(),
profiler_chan);
Pipeline::new(id,
subpage_id,
script_chan,
layout_chan,
render_chan)
/// This function wraps the task creation within a supervised task
/// so that failure will only tear down those tasks instead of ours.
pub fn spawn(chan:Chan<task::TaskResult>, f:~fn()) {
let mut task = task::task();
task.opts.notify_chan = Some(chan);
task.supervised();
do task.spawn {
f();
};
}

pub fn new(id: PipelineId,
Expand Down
1 change: 1 addition & 0 deletions src/components/msg/constellation_msg.rs
Expand Up @@ -35,6 +35,7 @@ pub enum IFrameSandboxState {

pub enum Msg {
ExitMsg(Chan<()>),
FailureMsg(PipelineId, Option<SubpageId>),
InitLoadUrlMsg(Url),
FrameRectMsg(PipelineId, SubpageId, Rect<f32>),
LoadUrlMsg(PipelineId, Url, Future<Size2D<uint>>),
Expand Down
Binary file added src/test/html/andreas.jpeg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions src/test/html/failure.html
@@ -0,0 +1,8 @@
<html>
<head>
<title>about:failure</title>
</head>
<body>
<img src="andreas.jpeg"/>
</body>
</html>
12 changes: 12 additions & 0 deletions src/test/html/summit-crash.html
@@ -0,0 +1,12 @@
<html>
<head>
<title>Summit demo crash page</title>
</head>
<body>
<audio>
<source src="horse.ogg" type="audio/ogg">
<source src="horse.mp3" type="audio/mpeg">
</audio>
<pre>pre</pre>
</body>
</html>
9 changes: 9 additions & 0 deletions src/test/html/summit-link.html
@@ -0,0 +1,9 @@
<html>
<head>
<title>Summit page linking to the crash page</title>
</head>

<body>
<a href="summit-crash.html">Load a crashing page</a>
</body>
</html>
12 changes: 12 additions & 0 deletions src/test/html/summit.html
@@ -0,0 +1,12 @@
<html>
<head>
<title>Summit demo page</title>
</head>
<body>
<iframe src="about-mozilla.html" style="display:block; border: 1px; width: 400px; height: 400px"
frameborder="yes" scrolling="yes"></iframe>

<iframe src="summit-link.html" style="display:block; border: 1px; width: 400px; height: 400px"
frameborder="yes" scrolling="yes"></iframe>
</body>
</html>

0 comments on commit 26ec022

Please sign in to comment.