diff --git a/Makefile.in b/Makefile.in index 3b89b0a8ac8..5ff62a288a7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 diff --git a/src/components/main/compositing/compositor_layer.rs b/src/components/main/compositing/compositor_layer.rs index e1a5324ef3e..34d942a32fb 100644 --- a/src/components/main/compositing/compositor_layer.rs +++ b/src/components/main/compositing/compositor_layer.rs @@ -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 + }}) } } diff --git a/src/components/main/constellation.rs b/src/components/main/constellation.rs index 271b72526bb..c38ec1d157d 100644 --- a/src/components/main/constellation.rs +++ b/src/components/main/constellation.rs @@ -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) { + 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, diff --git a/src/components/main/pipeline.rs b/src/components/main/pipeline.rs index 0204748c20b..0a716e0acf9 100644 --- a/src/components/main/pipeline.rs +++ b/src/components/main/pipeline.rs @@ -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::(); + + 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, f:~fn()) { + let mut task = task::task(); + task.opts.notify_chan = Some(chan); + task.supervised(); + do task.spawn { + f(); + }; } pub fn new(id: PipelineId, diff --git a/src/components/msg/constellation_msg.rs b/src/components/msg/constellation_msg.rs index c5b4dbb48d0..7724d53c429 100644 --- a/src/components/msg/constellation_msg.rs +++ b/src/components/msg/constellation_msg.rs @@ -35,6 +35,7 @@ pub enum IFrameSandboxState { pub enum Msg { ExitMsg(Chan<()>), + FailureMsg(PipelineId, Option), InitLoadUrlMsg(Url), FrameRectMsg(PipelineId, SubpageId, Rect), LoadUrlMsg(PipelineId, Url, Future>), diff --git a/src/test/html/andreas.jpeg b/src/test/html/andreas.jpeg new file mode 100644 index 00000000000..7aa813783bf Binary files /dev/null and b/src/test/html/andreas.jpeg differ diff --git a/src/test/html/failure.html b/src/test/html/failure.html new file mode 100644 index 00000000000..9f68ac9f0ff --- /dev/null +++ b/src/test/html/failure.html @@ -0,0 +1,8 @@ + + + about:failure + + + + + diff --git a/src/test/html/summit-crash.html b/src/test/html/summit-crash.html new file mode 100644 index 00000000000..7086941d0d5 --- /dev/null +++ b/src/test/html/summit-crash.html @@ -0,0 +1,12 @@ + + + Summit demo crash page + + + +
pre
+ + diff --git a/src/test/html/summit-link.html b/src/test/html/summit-link.html new file mode 100644 index 00000000000..77d1e704960 --- /dev/null +++ b/src/test/html/summit-link.html @@ -0,0 +1,9 @@ + + + Summit page linking to the crash page + + + + Load a crashing page + + diff --git a/src/test/html/summit.html b/src/test/html/summit.html new file mode 100644 index 00000000000..a74b40e593f --- /dev/null +++ b/src/test/html/summit.html @@ -0,0 +1,12 @@ + + + Summit demo page + + + + + + +