mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Pipeline create is now wrapped in a task that supervises the tasks
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.
This commit is contained in:
parent
4cf80cd49c
commit
26ec02226e
10 changed files with 166 additions and 34 deletions
|
@ -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))
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
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 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());
|
||||
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);
|
||||
Pipeline::new(id,
|
||||
subpage_id,
|
||||
script_chan,
|
||||
layout_chan,
|
||||
render_chan)
|
||||
LayoutTask::create(id,
|
||||
layout_port,
|
||||
constellation_chan,
|
||||
script_chan.clone(),
|
||||
render_chan.clone(),
|
||||
image_cache_task,
|
||||
opts.clone(),
|
||||
profiler_chan);
|
||||
};
|
||||
|
||||
do spawn {
|
||||
match port.recv() {
|
||||
task::Success => (),
|
||||
task::Failure => {
|
||||
let constellation_chan = constellation_chan_handler.take();
|
||||
constellation_chan.send(FailureMsg(id, subpage_id));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pipeline
|
||||
}
|
||||
|
||||
/// 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,
|
||||
|
|
|
@ -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>>),
|
||||
|
|
BIN
src/test/html/andreas.jpeg
Normal file
BIN
src/test/html/andreas.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 93 KiB |
8
src/test/html/failure.html
Normal file
8
src/test/html/failure.html
Normal file
|
@ -0,0 +1,8 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>about:failure</title>
|
||||
</head>
|
||||
<body>
|
||||
<img src="andreas.jpeg"/>
|
||||
</body>
|
||||
</html>
|
12
src/test/html/summit-crash.html
Normal file
12
src/test/html/summit-crash.html
Normal file
|
@ -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
src/test/html/summit-link.html
Normal file
9
src/test/html/summit-link.html
Normal file
|
@ -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
src/test/html/summit.html
Normal file
12
src/test/html/summit.html
Normal file
|
@ -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>
|
Loading…
Add table
Add a link
Reference in a new issue