From 4eb78753a6004ef84a41a20ce377bdbc00fccc5f Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Wed, 2 Jul 2014 09:15:16 +1000 Subject: [PATCH] Run render task on OS thread to avoid Skia memory corruption. When Skia is running on a green task, it can sometimes be rescheduled onto a different OS thread. This creates problems with the memory pool implementation in Skia, which uses TLS for storing the per thread memory pool information. Free'ing a pool allocation from a different OS thread than it was allocated on can cause heap corruption. FIXME: When we update rustc, switch the task failure message to using the new NativeTaskBuilder interface so that it can use the same send_on_failure function as green tasks. --- src/components/gfx/gfx.rs | 2 ++ src/components/gfx/render_task.rs | 21 +++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/components/gfx/gfx.rs b/src/components/gfx/gfx.rs index fcdb44f4815..dd7d58c7616 100644 --- a/src/components/gfx/gfx.rs +++ b/src/components/gfx/gfx.rs @@ -19,6 +19,8 @@ extern crate collections; extern crate geom; extern crate layers; extern crate libc; +extern crate native; +extern crate rustrt; extern crate stb_image; extern crate png; #[phase(plugin)] diff --git a/src/components/gfx/render_task.rs b/src/components/gfx/render_task.rs index 19b8e3891b3..17c5e23f657 100644 --- a/src/components/gfx/render_task.rs +++ b/src/components/gfx/render_task.rs @@ -18,6 +18,9 @@ use geom::size::Size2D; use layers::platform::surface::{NativePaintingGraphicsContext, NativeSurface}; use layers::platform::surface::{NativeSurfaceMethods}; use layers; +use native; +use rustrt::task; +use rustrt::task::TaskOpts; use servo_msg::compositor_msg::{Epoch, IdleRenderState, LayerBuffer, LayerBufferSet, LayerId}; use servo_msg::compositor_msg::{LayerMetadata, RenderListener, RenderingRenderState, ScrollPolicy}; use servo_msg::constellation_msg::{ConstellationChan, Failure, FailureMsg, PipelineId}; @@ -26,11 +29,9 @@ use servo_msg::platform::surface::NativeSurfaceAzureMethods; use servo_util::geometry; use servo_util::opts::Opts; use servo_util::smallvec::{SmallVec, SmallVec1}; -use servo_util::task::send_on_failure; use servo_util::time::{TimeProfilerChan, profile}; use servo_util::time; use std::comm::{Receiver, Sender, channel}; -use std::task::TaskBuilder; use sync::Arc; /// Information about a layer that layout sends to the painting task. @@ -163,11 +164,19 @@ impl RenderTask { opts: Opts, time_profiler_chan: TimeProfilerChan, shutdown_chan: Sender<()>) { - let mut builder = TaskBuilder::new().named("RenderTask"); - let ConstellationChan(c) = constellation_chan.clone(); - send_on_failure(&mut builder, FailureMsg(failure_msg), c); - builder.spawn(proc() { + let ConstellationChan(c) = constellation_chan.clone(); + let mut task_opts = TaskOpts::new(); + task_opts.name = Some("RenderTask".into_maybe_owned()); + task_opts.on_exit = Some(proc(result: task::Result) { + match result { + Ok(()) => {}, + Err(..) => { + c.send(FailureMsg(failure_msg)); + } + } + }); + native::task::spawn_opts(task_opts, proc() { { // Ensures RenderTask and graphics context are destroyed before shutdown msg let native_graphics_context = compositor.get_graphics_metadata().map( |md| NativePaintingGraphicsContext::from_metadata(&md));