mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Restore failure handling
We probably leak some threads and resources, e.g. when the script task crashes and doesn't get a chance to send layout data back to layout to be deallocated. Not tested with iframes yet.
This commit is contained in:
parent
68cc30c1df
commit
36b8f63984
7 changed files with 88 additions and 40 deletions
|
@ -15,12 +15,14 @@ use layers;
|
||||||
use servo_msg::compositor_msg::{Epoch, IdleRenderState, LayerBuffer, LayerBufferSet};
|
use servo_msg::compositor_msg::{Epoch, IdleRenderState, LayerBuffer, LayerBufferSet};
|
||||||
use servo_msg::compositor_msg::{RenderListener, RenderingRenderState};
|
use servo_msg::compositor_msg::{RenderListener, RenderingRenderState};
|
||||||
use servo_msg::constellation_msg::{ConstellationChan, PipelineId, RendererReadyMsg};
|
use servo_msg::constellation_msg::{ConstellationChan, PipelineId, RendererReadyMsg};
|
||||||
|
use servo_msg::constellation_msg::{Failure, FailureMsg};
|
||||||
use servo_msg::platform::surface::NativeSurfaceAzureMethods;
|
use servo_msg::platform::surface::NativeSurfaceAzureMethods;
|
||||||
use servo_util::time::{ProfilerChan, profile};
|
use servo_util::time::{ProfilerChan, profile};
|
||||||
use servo_util::time;
|
use servo_util::time;
|
||||||
use servo_util::task::spawn_named;
|
use servo_util::task::send_on_failure;
|
||||||
|
|
||||||
use std::comm::{Chan, Port, SharedChan};
|
use std::comm::{Chan, Port, SharedChan};
|
||||||
|
use std::task;
|
||||||
use extra::arc::Arc;
|
use extra::arc::Arc;
|
||||||
|
|
||||||
use buffer_map::BufferMap;
|
use buffer_map::BufferMap;
|
||||||
|
@ -41,7 +43,7 @@ pub enum Msg<T> {
|
||||||
UnusedBufferMsg(~[~LayerBuffer]),
|
UnusedBufferMsg(~[~LayerBuffer]),
|
||||||
PaintPermissionGranted,
|
PaintPermissionGranted,
|
||||||
PaintPermissionRevoked,
|
PaintPermissionRevoked,
|
||||||
ExitMsg(Chan<()>),
|
ExitMsg(Option<Chan<()>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A request from the compositor to the renderer for tiles that need to be (re)displayed.
|
/// A request from the compositor to the renderer for tiles that need to be (re)displayed.
|
||||||
|
@ -143,10 +145,14 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
|
||||||
port: Port<Msg<T>>,
|
port: Port<Msg<T>>,
|
||||||
compositor: C,
|
compositor: C,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
|
failure_msg: Failure,
|
||||||
opts: Opts,
|
opts: Opts,
|
||||||
profiler_chan: ProfilerChan,
|
profiler_chan: ProfilerChan,
|
||||||
shutdown_chan: Chan<()>) {
|
shutdown_chan: Chan<()>) {
|
||||||
spawn_named("RenderTask", proc() {
|
let mut builder = task::task();
|
||||||
|
send_on_failure(&mut builder, FailureMsg(failure_msg), (*constellation_chan).clone());
|
||||||
|
builder.name("RenderTask");
|
||||||
|
builder.spawn(proc() {
|
||||||
|
|
||||||
{ // Ensures RenderTask and graphics context are destroyed before shutdown msg
|
{ // Ensures RenderTask and graphics context are destroyed before shutdown msg
|
||||||
let native_graphics_context = compositor.get_graphics_metadata().map(
|
let native_graphics_context = compositor.get_graphics_metadata().map(
|
||||||
|
@ -237,7 +243,7 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
|
||||||
}
|
}
|
||||||
ExitMsg(response_ch) => {
|
ExitMsg(response_ch) => {
|
||||||
debug!("render_task: exitmsg response send");
|
debug!("render_task: exitmsg response send");
|
||||||
response_ch.send(());
|
response_ch.map(|ch| ch.send(()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -382,7 +382,7 @@ impl IOCompositor {
|
||||||
let world_zoom = self.world_zoom;
|
let world_zoom = self.world_zoom;
|
||||||
let page_window = Size2D(window_size.width as f32 / world_zoom,
|
let page_window = Size2D(window_size.width as f32 / world_zoom,
|
||||||
window_size.height as f32 / world_zoom);
|
window_size.height as f32 / world_zoom);
|
||||||
assert!(layer.resize(id, new_size, page_window, epoch));
|
layer.resize(id, new_size, page_window, epoch);
|
||||||
let move = self.fragment_point.take().map_default(false, |point| layer.move(point, page_window));
|
let move = self.fragment_point.take().map_default(false, |point| layer.move(point, page_window));
|
||||||
|
|
||||||
(true, move)
|
(true, move)
|
||||||
|
|
|
@ -248,12 +248,12 @@ impl CompositorLayer {
|
||||||
MouseWindowMouseDownEvent(button, _) => MouseDownEvent(button, cursor),
|
MouseWindowMouseDownEvent(button, _) => MouseDownEvent(button, cursor),
|
||||||
MouseWindowMouseUpEvent(button, _) => MouseUpEvent(button, cursor),
|
MouseWindowMouseUpEvent(button, _) => MouseUpEvent(button, cursor),
|
||||||
};
|
};
|
||||||
self.pipeline.script_chan.send(SendEventMsg(self.pipeline.id.clone(), message));
|
self.pipeline.script_chan.try_send(SendEventMsg(self.pipeline.id.clone(), message));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_mouse_move_event(&self, cursor: Point2D<f32>) {
|
pub fn send_mouse_move_event(&self, cursor: Point2D<f32>) {
|
||||||
let message = MouseMoveEvent(cursor);
|
let message = MouseMoveEvent(cursor);
|
||||||
self.pipeline.script_chan.send(SendEventMsg(self.pipeline.id.clone(), message));
|
self.pipeline.script_chan.try_send(SendEventMsg(self.pipeline.id.clone(), message));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given the current window size, determine which tiles need to be (re)rendered
|
// Given the current window size, determine which tiles need to be (re)rendered
|
||||||
|
@ -277,7 +277,7 @@ impl CompositorLayer {
|
||||||
let (request, unused) = quadtree.get_tile_rects_page(rect, scale);
|
let (request, unused) = quadtree.get_tile_rects_page(rect, scale);
|
||||||
redisplay = !unused.is_empty(); // workaround to make redisplay visible outside block
|
redisplay = !unused.is_empty(); // workaround to make redisplay visible outside block
|
||||||
if redisplay { // send back unused tiles
|
if redisplay { // send back unused tiles
|
||||||
self.pipeline.render_chan.send(UnusedBufferMsg(unused));
|
self.pipeline.render_chan.try_send(UnusedBufferMsg(unused));
|
||||||
}
|
}
|
||||||
if !request.is_empty() { // ask for tiles
|
if !request.is_empty() { // ask for tiles
|
||||||
self.pipeline.render_chan.try_send(ReRenderMsg(request, scale, self.epoch));
|
self.pipeline.render_chan.try_send(ReRenderMsg(request, scale, self.epoch));
|
||||||
|
@ -365,7 +365,7 @@ impl CompositorLayer {
|
||||||
self.page_size = Some(new_size);
|
self.page_size = Some(new_size);
|
||||||
match self.quadtree {
|
match self.quadtree {
|
||||||
Tree(ref mut quadtree) => {
|
Tree(ref mut quadtree) => {
|
||||||
self.pipeline.render_chan.send(UnusedBufferMsg(quadtree.resize(new_size.width as uint,
|
self.pipeline.render_chan.try_send(UnusedBufferMsg(quadtree.resize(new_size.width as uint,
|
||||||
new_size.height as uint)));
|
new_size.height as uint)));
|
||||||
}
|
}
|
||||||
NoTree(tile_size, max_mem) => {
|
NoTree(tile_size, max_mem) => {
|
||||||
|
@ -455,7 +455,7 @@ impl CompositorLayer {
|
||||||
child.page_size = Some(new_size);
|
child.page_size = Some(new_size);
|
||||||
match child.quadtree {
|
match child.quadtree {
|
||||||
Tree(ref mut quadtree) => {
|
Tree(ref mut quadtree) => {
|
||||||
child.pipeline.render_chan.send(UnusedBufferMsg(quadtree.resize(new_size.width as uint,
|
child.pipeline.render_chan.try_send(UnusedBufferMsg(quadtree.resize(new_size.width as uint,
|
||||||
new_size.height as uint)));
|
new_size.height as uint)));
|
||||||
}
|
}
|
||||||
NoTree(tile_size, max_mem) => {
|
NoTree(tile_size, max_mem) => {
|
||||||
|
@ -596,7 +596,7 @@ impl CompositorLayer {
|
||||||
self.epoch,
|
self.epoch,
|
||||||
epoch,
|
epoch,
|
||||||
self.pipeline.id);
|
self.pipeline.id);
|
||||||
self.pipeline.render_chan.send(UnusedBufferMsg(new_buffers.buffers));
|
self.pipeline.render_chan.try_send(UnusedBufferMsg(new_buffers.buffers));
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,7 +615,7 @@ impl CompositorLayer {
|
||||||
buffer.resolution, buffer));
|
buffer.resolution, buffer));
|
||||||
}
|
}
|
||||||
if !unused_tiles.is_empty() { // send back unused buffers
|
if !unused_tiles.is_empty() { // send back unused buffers
|
||||||
self.pipeline.render_chan.send(UnusedBufferMsg(unused_tiles));
|
self.pipeline.render_chan.try_send(UnusedBufferMsg(unused_tiles));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.build_layer_tree(graphics_context);
|
self.build_layer_tree(graphics_context);
|
||||||
|
@ -719,7 +719,7 @@ impl CompositorLayer {
|
||||||
tile.mark_wont_leak()
|
tile.mark_wont_leak()
|
||||||
}
|
}
|
||||||
|
|
||||||
self.pipeline.render_chan.send(UnusedBufferMsg(tiles))
|
self.pipeline.render_chan.try_send(UnusedBufferMsg(tiles));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,10 @@ use extra::url::Url;
|
||||||
use geom::rect::Rect;
|
use geom::rect::Rect;
|
||||||
use geom::size::Size2D;
|
use geom::size::Size2D;
|
||||||
use gfx::opts::Opts;
|
use gfx::opts::Opts;
|
||||||
|
use gfx::render_task;
|
||||||
use pipeline::{Pipeline, CompositionPipeline};
|
use pipeline::{Pipeline, CompositionPipeline};
|
||||||
use script::script_task::{ResizeMsg, ResizeInactiveMsg};
|
use script::script_task::{ResizeMsg, ResizeInactiveMsg, ExitPipelineMsg};
|
||||||
|
use script::layout_interface;
|
||||||
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, FailureMsg, Failure, FrameRectMsg};
|
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, FailureMsg, Failure, FrameRectMsg};
|
||||||
use servo_msg::constellation_msg::{IFrameSandboxState, IFrameUnsandboxed, InitLoadUrlMsg};
|
use servo_msg::constellation_msg::{IFrameSandboxState, IFrameUnsandboxed, InitLoadUrlMsg};
|
||||||
use servo_msg::constellation_msg::{LoadCompleteMsg, LoadIframeUrlMsg, LoadUrlMsg, Msg, NavigateMsg};
|
use servo_msg::constellation_msg::{LoadCompleteMsg, LoadIframeUrlMsg, LoadUrlMsg, Msg, NavigateMsg};
|
||||||
|
@ -380,6 +382,18 @@ impl Constellation {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_failure_msg(&mut self, pipeline_id: PipelineId, subpage_id: Option<SubpageId>) {
|
fn handle_failure_msg(&mut self, pipeline_id: PipelineId, subpage_id: Option<SubpageId>) {
|
||||||
|
debug!("handling failure message from pipeline {:?}, {:?}", pipeline_id, subpage_id);
|
||||||
|
|
||||||
|
let old_pipeline = match self.pipelines.find(&pipeline_id) {
|
||||||
|
None => return, // already failed?
|
||||||
|
Some(id) => *id
|
||||||
|
};
|
||||||
|
|
||||||
|
old_pipeline.script_chan.try_send(ExitPipelineMsg(pipeline_id));
|
||||||
|
old_pipeline.render_chan.try_send(render_task::ExitMsg(None));
|
||||||
|
old_pipeline.layout_chan.try_send(layout_interface::ExitNowMsg);
|
||||||
|
self.pipelines.remove(&pipeline_id);
|
||||||
|
|
||||||
let new_id = self.get_next_pipeline_id();
|
let new_id = self.get_next_pipeline_id();
|
||||||
let pipeline = @mut Pipeline::create(new_id,
|
let pipeline = @mut Pipeline::create(new_id,
|
||||||
subpage_id,
|
subpage_id,
|
||||||
|
@ -390,16 +404,20 @@ impl Constellation {
|
||||||
self.profiler_chan.clone(),
|
self.profiler_chan.clone(),
|
||||||
self.window_size,
|
self.window_size,
|
||||||
self.opts.clone());
|
self.opts.clone());
|
||||||
let failure = "about:failure";
|
|
||||||
let url = parse_url(failure, None);
|
self.pipelines.insert(new_id, pipeline);
|
||||||
|
let url = parse_url("about:failure", None);
|
||||||
pipeline.load(url);
|
pipeline.load(url);
|
||||||
|
|
||||||
let frames = self.find_all(pipeline_id);
|
self.pending_frames.push(FrameChange{
|
||||||
for frame_tree in frames.iter() {
|
before: Some(pipeline_id),
|
||||||
frame_tree.pipeline = pipeline;
|
after: @mut FrameTree {
|
||||||
};
|
pipeline: pipeline,
|
||||||
|
parent: None,
|
||||||
self.pipelines.insert(pipeline_id, pipeline);
|
children: ~[],
|
||||||
|
},
|
||||||
|
navigation_type: constellation_msg::Navigate,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_init_load(&mut self, url: Url) {
|
fn handle_init_load(&mut self, url: Url) {
|
||||||
|
|
|
@ -40,19 +40,20 @@ use script::layout_interface::{ContentChangedDocumentDamage, LayoutChan, Msg, Pr
|
||||||
use script::layout_interface::{QueryMsg, ReapLayoutDataMsg, Reflow, ReflowDocumentDamage, UntrustedNodeAddress};
|
use script::layout_interface::{QueryMsg, ReapLayoutDataMsg, Reflow, ReflowDocumentDamage, UntrustedNodeAddress};
|
||||||
use script::layout_interface::{ReflowForDisplay, ReflowMsg};
|
use script::layout_interface::{ReflowForDisplay, ReflowMsg};
|
||||||
use script::script_task::{ReflowCompleteMsg, ScriptChan, SendEventMsg};
|
use script::script_task::{ReflowCompleteMsg, ScriptChan, SendEventMsg};
|
||||||
use servo_msg::constellation_msg::{ConstellationChan, PipelineId};
|
use servo_msg::constellation_msg::{ConstellationChan, PipelineId, Failure, FailureMsg};
|
||||||
use servo_net::image_cache_task::{ImageCacheTask, ImageResponseMsg};
|
use servo_net::image_cache_task::{ImageCacheTask, ImageResponseMsg};
|
||||||
use servo_net::local_image_cache::{ImageResponder, LocalImageCache};
|
use servo_net::local_image_cache::{ImageResponder, LocalImageCache};
|
||||||
use servo_util::geometry::Au;
|
use servo_util::geometry::Au;
|
||||||
use servo_util::time::{ProfilerChan, profile};
|
use servo_util::time::{ProfilerChan, profile};
|
||||||
use servo_util::time;
|
use servo_util::time;
|
||||||
use servo_util::task::spawn_named;
|
use servo_util::task::send_on_failure;
|
||||||
use servo_util::workqueue::WorkQueue;
|
use servo_util::workqueue::WorkQueue;
|
||||||
use std::cast::transmute;
|
use std::cast::transmute;
|
||||||
use std::cast;
|
use std::cast;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::comm::Port;
|
use std::comm::Port;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
use std::task;
|
||||||
use std::util;
|
use std::util;
|
||||||
use style::{AuthorOrigin, Stylesheet, Stylist};
|
use style::{AuthorOrigin, Stylesheet, Stylist};
|
||||||
|
|
||||||
|
@ -240,13 +241,17 @@ impl LayoutTask {
|
||||||
port: Port<Msg>,
|
port: Port<Msg>,
|
||||||
chan: LayoutChan,
|
chan: LayoutChan,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
|
failure_msg: Failure,
|
||||||
script_chan: ScriptChan,
|
script_chan: ScriptChan,
|
||||||
render_chan: RenderChan<OpaqueNode>,
|
render_chan: RenderChan<OpaqueNode>,
|
||||||
img_cache_task: ImageCacheTask,
|
img_cache_task: ImageCacheTask,
|
||||||
opts: Opts,
|
opts: Opts,
|
||||||
profiler_chan: ProfilerChan,
|
profiler_chan: ProfilerChan,
|
||||||
shutdown_chan: Chan<()>) {
|
shutdown_chan: Chan<()>) {
|
||||||
spawn_named("LayoutTask", proc() {
|
let mut builder = task::task();
|
||||||
|
send_on_failure(&mut builder, FailureMsg(failure_msg), (*constellation_chan).clone());
|
||||||
|
builder.name("LayoutTask");
|
||||||
|
builder.spawn(proc() {
|
||||||
{ // Ensures layout task is destroyed before we send shutdown message
|
{ // Ensures layout task is destroyed before we send shutdown message
|
||||||
let mut layout = LayoutTask::new(id,
|
let mut layout = LayoutTask::new(id,
|
||||||
port,
|
port,
|
||||||
|
@ -400,7 +405,7 @@ impl LayoutTask {
|
||||||
Some(ref mut traversal) => traversal.shutdown(),
|
Some(ref mut traversal) => traversal.shutdown(),
|
||||||
}
|
}
|
||||||
|
|
||||||
self.render_chan.send(render_task::ExitMsg(response_chan));
|
self.render_chan.send(render_task::ExitMsg(Some(response_chan)));
|
||||||
response_port.recv()
|
response_port.recv()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ use script::layout_interface::LayoutChan;
|
||||||
use script::script_task::LoadMsg;
|
use script::script_task::LoadMsg;
|
||||||
use script::script_task::{AttachLayoutMsg, NewLayoutInfo, ScriptTask, ScriptChan};
|
use script::script_task::{AttachLayoutMsg, NewLayoutInfo, ScriptTask, ScriptChan};
|
||||||
use script::script_task;
|
use script::script_task;
|
||||||
use servo_msg::constellation_msg::{ConstellationChan, PipelineId, SubpageId};
|
use servo_msg::constellation_msg::{ConstellationChan, Failure, PipelineId, SubpageId};
|
||||||
use servo_net::image_cache_task::ImageCacheTask;
|
use servo_net::image_cache_task::ImageCacheTask;
|
||||||
use servo_net::resource_task::ResourceTask;
|
use servo_net::resource_task::ResourceTask;
|
||||||
use servo_util::time::ProfilerChan;
|
use servo_util::time::ProfilerChan;
|
||||||
|
@ -58,10 +58,16 @@ impl Pipeline {
|
||||||
let (render_shutdown_port, render_shutdown_chan) = Chan::new();
|
let (render_shutdown_port, render_shutdown_chan) = Chan::new();
|
||||||
let (layout_shutdown_port, layout_shutdown_chan) = Chan::new();
|
let (layout_shutdown_port, layout_shutdown_chan) = Chan::new();
|
||||||
|
|
||||||
|
let failure = Failure {
|
||||||
|
pipeline_id: id,
|
||||||
|
subpage_id: subpage_id,
|
||||||
|
};
|
||||||
|
|
||||||
RenderTask::create(id,
|
RenderTask::create(id,
|
||||||
render_port,
|
render_port,
|
||||||
compositor_chan.clone(),
|
compositor_chan.clone(),
|
||||||
constellation_chan.clone(),
|
constellation_chan.clone(),
|
||||||
|
failure.clone(),
|
||||||
opts.clone(),
|
opts.clone(),
|
||||||
profiler_chan.clone(),
|
profiler_chan.clone(),
|
||||||
render_shutdown_chan);
|
render_shutdown_chan);
|
||||||
|
@ -70,6 +76,7 @@ impl Pipeline {
|
||||||
layout_port,
|
layout_port,
|
||||||
layout_chan.clone(),
|
layout_chan.clone(),
|
||||||
constellation_chan,
|
constellation_chan,
|
||||||
|
failure,
|
||||||
script_pipeline.script_chan.clone(),
|
script_pipeline.script_chan.clone(),
|
||||||
render_chan.clone(),
|
render_chan.clone(),
|
||||||
image_cache_task.clone(),
|
image_cache_task.clone(),
|
||||||
|
@ -117,7 +124,10 @@ impl Pipeline {
|
||||||
layout_shutdown_port,
|
layout_shutdown_port,
|
||||||
render_shutdown_port);
|
render_shutdown_port);
|
||||||
|
|
||||||
// FIXME(#1434): add back failure supervision
|
let failure = Failure {
|
||||||
|
pipeline_id: id,
|
||||||
|
subpage_id: subpage_id,
|
||||||
|
};
|
||||||
|
|
||||||
ScriptTask::create(id,
|
ScriptTask::create(id,
|
||||||
compositor_chan.clone(),
|
compositor_chan.clone(),
|
||||||
|
@ -125,6 +135,7 @@ impl Pipeline {
|
||||||
script_port,
|
script_port,
|
||||||
script_chan.clone(),
|
script_chan.clone(),
|
||||||
constellation_chan.clone(),
|
constellation_chan.clone(),
|
||||||
|
failure.clone(),
|
||||||
resource_task,
|
resource_task,
|
||||||
image_cache_task.clone(),
|
image_cache_task.clone(),
|
||||||
window_size);
|
window_size);
|
||||||
|
@ -133,6 +144,7 @@ impl Pipeline {
|
||||||
render_port,
|
render_port,
|
||||||
compositor_chan.clone(),
|
compositor_chan.clone(),
|
||||||
constellation_chan.clone(),
|
constellation_chan.clone(),
|
||||||
|
failure.clone(),
|
||||||
opts.clone(),
|
opts.clone(),
|
||||||
profiler_chan.clone(),
|
profiler_chan.clone(),
|
||||||
render_shutdown_chan);
|
render_shutdown_chan);
|
||||||
|
@ -141,6 +153,7 @@ impl Pipeline {
|
||||||
layout_port,
|
layout_port,
|
||||||
layout_chan.clone(),
|
layout_chan.clone(),
|
||||||
constellation_chan,
|
constellation_chan,
|
||||||
|
failure,
|
||||||
script_chan.clone(),
|
script_chan.clone(),
|
||||||
render_chan.clone(),
|
render_chan.clone(),
|
||||||
image_cache_task,
|
image_cache_task,
|
||||||
|
@ -182,7 +195,7 @@ impl Pipeline {
|
||||||
|
|
||||||
pub fn revoke_paint_permission(&self) {
|
pub fn revoke_paint_permission(&self) {
|
||||||
debug!("pipeline revoking render channel paint permission");
|
debug!("pipeline revoking render channel paint permission");
|
||||||
self.render_chan.send(PaintPermissionRevoked);
|
self.render_chan.try_send(PaintPermissionRevoked);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reload(&mut self) {
|
pub fn reload(&mut self) {
|
||||||
|
@ -193,13 +206,14 @@ impl Pipeline {
|
||||||
|
|
||||||
pub fn exit(&self) {
|
pub fn exit(&self) {
|
||||||
// Script task handles shutting down layout, and layout handles shutting down the renderer.
|
// Script task handles shutting down layout, and layout handles shutting down the renderer.
|
||||||
self.script_chan.try_send(script_task::ExitPipelineMsg(self.id));
|
// For now, if the script task has failed, we give up on clean shutdown.
|
||||||
|
if self.script_chan.try_send(script_task::ExitPipelineMsg(self.id)) {
|
||||||
// Wait until all slave tasks have terminated and run destructors
|
// Wait until all slave tasks have terminated and run destructors
|
||||||
// NOTE: We don't wait for script task as we don't always own it
|
// NOTE: We don't wait for script task as we don't always own it
|
||||||
self.render_shutdown_port.recv_opt();
|
self.render_shutdown_port.recv_opt();
|
||||||
self.layout_shutdown_port.recv_opt();
|
self.layout_shutdown_port.recv_opt();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn to_sendable(&self) -> CompositionPipeline {
|
pub fn to_sendable(&self) -> CompositionPipeline {
|
||||||
CompositionPipeline {
|
CompositionPipeline {
|
||||||
|
|
|
@ -39,17 +39,18 @@ use js;
|
||||||
use servo_msg::compositor_msg::{FinishedLoading, Loading, PerformingLayout, ScriptListener};
|
use servo_msg::compositor_msg::{FinishedLoading, Loading, PerformingLayout, ScriptListener};
|
||||||
use servo_msg::constellation_msg::{ConstellationChan, IFrameSandboxed, IFrameUnsandboxed};
|
use servo_msg::constellation_msg::{ConstellationChan, IFrameSandboxed, IFrameUnsandboxed};
|
||||||
use servo_msg::constellation_msg::{LoadIframeUrlMsg, LoadCompleteMsg, LoadUrlMsg, NavigationDirection};
|
use servo_msg::constellation_msg::{LoadIframeUrlMsg, LoadCompleteMsg, LoadUrlMsg, NavigationDirection};
|
||||||
use servo_msg::constellation_msg::{PipelineId, SubpageId};
|
use servo_msg::constellation_msg::{PipelineId, SubpageId, Failure, FailureMsg};
|
||||||
use servo_msg::constellation_msg;
|
use servo_msg::constellation_msg;
|
||||||
use servo_net::image_cache_task::ImageCacheTask;
|
use servo_net::image_cache_task::ImageCacheTask;
|
||||||
use servo_net::resource_task::ResourceTask;
|
use servo_net::resource_task::ResourceTask;
|
||||||
use servo_util::geometry::to_frac_px;
|
use servo_util::geometry::to_frac_px;
|
||||||
use servo_util::url::parse_url;
|
use servo_util::url::parse_url;
|
||||||
use servo_util::task::spawn_named;
|
use servo_util::task::send_on_failure;
|
||||||
use servo_util::namespace::Null;
|
use servo_util::namespace::Null;
|
||||||
use std::comm::{Port, SharedChan};
|
use std::comm::{Port, SharedChan};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::str::eq_slice;
|
use std::str::eq_slice;
|
||||||
|
use std::task;
|
||||||
use std::util::replace;
|
use std::util::replace;
|
||||||
|
|
||||||
/// Messages used to control the script task.
|
/// Messages used to control the script task.
|
||||||
|
@ -463,10 +464,14 @@ impl ScriptTask {
|
||||||
port: Port<ScriptMsg>,
|
port: Port<ScriptMsg>,
|
||||||
chan: ScriptChan,
|
chan: ScriptChan,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
|
failure_msg: Failure,
|
||||||
resource_task: ResourceTask,
|
resource_task: ResourceTask,
|
||||||
image_cache_task: ImageCacheTask,
|
image_cache_task: ImageCacheTask,
|
||||||
window_size: Size2D<uint>) {
|
window_size: Size2D<uint>) {
|
||||||
spawn_named("ScriptTask", proc() {
|
let mut builder = task::task();
|
||||||
|
send_on_failure(&mut builder, FailureMsg(failure_msg), (*constellation_chan).clone());
|
||||||
|
builder.name("ScriptTask");
|
||||||
|
builder.spawn(proc() {
|
||||||
let script_task = ScriptTask::new(id,
|
let script_task = ScriptTask::new(id,
|
||||||
@compositor as @ScriptListener,
|
@compositor as @ScriptListener,
|
||||||
layout_chan,
|
layout_chan,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue