diff options
-rw-r--r-- | components/constellation/constellation.rs | 133 | ||||
-rw-r--r-- | components/constellation/pipeline.rs | 329 |
2 files changed, 214 insertions, 248 deletions
diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 383a9a8d394..1aa3650d791 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -19,14 +19,8 @@ use compositing::compositor_thread::Msg as ToCompositorMsg; use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg}; use euclid::scale_factor::ScaleFactor; use euclid::size::{Size2D, TypedSize2D}; -#[cfg(not(target_os = "windows"))] -use gaol; -#[cfg(not(target_os = "windows"))] -use gaol::sandbox::{self, Sandbox, SandboxMethods}; use gfx::font_cache_thread::FontCacheThread; use gfx_traits::Epoch; -#[cfg(not(target_os = "windows"))] -use ipc_channel::ipc::IpcOneShotServer; use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::router::ROUTER; use layout_traits::{LayoutControlChan, LayoutThreadFactory}; @@ -43,12 +37,10 @@ use net_traits::image_cache_thread::ImageCacheThread; use net_traits::storage_thread::StorageThreadMsg; use net_traits::{self, ResourceThreads, IpcSend}; use offscreen_gl_context::{GLContextAttributes, GLLimits}; -use pipeline::{InitialPipelineState, Pipeline, UnprivilegedPipelineContent}; +use pipeline::{ChildProcess, InitialPipelineState, Pipeline}; use profile_traits::mem; use profile_traits::time; use rand::{random, Rng, SeedableRng, StdRng}; -#[cfg(not(target_os = "windows"))] -use sandboxing::content_process_sandbox_profile; use script_traits::{AnimationState, AnimationTickType, CompositorEvent}; use script_traits::{ConstellationControlMsg, ConstellationMsg as FromCompositorMsg}; use script_traits::{DocumentState, LayoutControlMsg}; @@ -57,8 +49,6 @@ use script_traits::{LayoutMsg as FromLayoutMsg, ScriptMsg as FromScriptMsg, Scri use script_traits::{MozBrowserEvent, MozBrowserErrorType}; use std::borrow::ToOwned; use std::collections::HashMap; -#[cfg(not(target_os = "windows"))] -use std::env; use std::io::Error as IOError; use std::marker::PhantomData; use std::mem::replace; @@ -313,13 +303,6 @@ enum ExitPipelineMode { Force, } -enum ChildProcess { - #[cfg(not(target_os = "windows"))] - Sandboxed(gaol::platform::process::Process), - #[cfg(not(target_os = "windows"))] - Unsandboxed(process::Child), -} - impl<Message, LTF, STF> Constellation<Message, LTF, STF> where LTF: LayoutThreadFactory<Message=Message>, STF: ScriptThreadFactory<Message=Message> @@ -424,100 +407,42 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> initial_window_size: Option<TypedSize2D<PagePx, f32>>, script_channel: Option<IpcSender<ConstellationControlMsg>>, load_data: LoadData) { - let spawning_content = script_channel.is_none(); - let (pipeline, unprivileged_pipeline_content, privileged_pipeline_content) = - Pipeline::create::<LTF, STF>(InitialPipelineState { - id: pipeline_id, - parent_info: parent_info, - constellation_chan: self.script_sender.clone(), - layout_to_constellation_chan: self.layout_sender.clone(), - panic_chan: self.panic_sender.clone(), - scheduler_chan: self.scheduler_chan.clone(), - compositor_proxy: self.compositor_proxy.clone_compositor_proxy(), - devtools_chan: self.devtools_chan.clone(), - bluetooth_thread: self.bluetooth_thread.clone(), - image_cache_thread: self.image_cache_thread.clone(), - font_cache_thread: self.font_cache_thread.clone(), - resource_threads: self.resource_threads.clone(), - time_profiler_chan: self.time_profiler_chan.clone(), - mem_profiler_chan: self.mem_profiler_chan.clone(), - window_size: initial_window_size, - script_chan: script_channel, - load_data: load_data, - device_pixel_ratio: self.window_size.device_pixel_ratio, - pipeline_namespace_id: self.next_pipeline_namespace_id(), - webrender_api_sender: self.webrender_api_sender.clone(), - }); + let result = Pipeline::spawn::<Message, LTF, STF>(InitialPipelineState { + id: pipeline_id, + parent_info: parent_info, + constellation_chan: self.script_sender.clone(), + layout_to_constellation_chan: self.layout_sender.clone(), + panic_chan: self.panic_sender.clone(), + scheduler_chan: self.scheduler_chan.clone(), + compositor_proxy: self.compositor_proxy.clone_compositor_proxy(), + devtools_chan: self.devtools_chan.clone(), + bluetooth_thread: self.bluetooth_thread.clone(), + image_cache_thread: self.image_cache_thread.clone(), + font_cache_thread: self.font_cache_thread.clone(), + resource_threads: self.resource_threads.clone(), + time_profiler_chan: self.time_profiler_chan.clone(), + mem_profiler_chan: self.mem_profiler_chan.clone(), + window_size: initial_window_size, + script_chan: script_channel, + load_data: load_data, + device_pixel_ratio: self.window_size.device_pixel_ratio, + pipeline_namespace_id: self.next_pipeline_namespace_id(), + webrender_api_sender: self.webrender_api_sender.clone(), + }); - privileged_pipeline_content.start(); + let (pipeline, child_process) = match result { + Ok(result) => result, + Err(e) => return self.handle_send_error(pipeline_id, e), + }; - if spawning_content { - // Spawn the child process. - // - // Yes, that's all there is to it! - if opts::multiprocess() { - self.spawn_multiprocess(pipeline_id, unprivileged_pipeline_content); - } else { - unprivileged_pipeline_content.start_all::<Message, LTF, STF>(false); - } + if let Some(child_process) = child_process { + self.child_processes.push(child_process); } assert!(!self.pipelines.contains_key(&pipeline_id)); self.pipelines.insert(pipeline_id, pipeline); } - #[cfg(not(target_os = "windows"))] - fn spawn_multiprocess(&mut self, - pipeline_id: PipelineId, - unprivileged_pipeline_content: UnprivilegedPipelineContent) - { - // Note that this function can panic, due to process creation, - // avoiding this panic would require a mechanism for dealing - // with low-resource scenarios. - let (server, token) = - IpcOneShotServer::<IpcSender<UnprivilegedPipelineContent>>::new() - .expect("Failed to create IPC one-shot server."); - - // If there is a sandbox, use the `gaol` API to create the child process. - let child_process = if opts::get().sandbox { - let mut command = sandbox::Command::me().expect("Failed to get current sandbox."); - command.arg("--content-process").arg(token); - - if let Ok(value) = env::var("RUST_BACKTRACE") { - command.env("RUST_BACKTRACE", value); - } - - let profile = content_process_sandbox_profile(); - ChildProcess::Sandboxed(Sandbox::new(profile).start(&mut command) - .expect("Failed to start sandboxed child process!")) - } else { - let path_to_self = env::current_exe() - .expect("Failed to get current executor."); - let mut child_process = process::Command::new(path_to_self); - child_process.arg("--content-process"); - child_process.arg(token); - - if let Ok(value) = env::var("RUST_BACKTRACE") { - child_process.env("RUST_BACKTRACE", value); - } - - ChildProcess::Unsandboxed(child_process.spawn() - .expect("Failed to start unsandboxed child process!")) - }; - - self.child_processes.push(child_process); - let (_receiver, sender) = server.accept().expect("Server failed to accept."); - if let Err(e) = sender.send(unprivileged_pipeline_content) { - self.handle_send_error(pipeline_id, e); - } - } - - #[cfg(target_os = "windows")] - fn spawn_multiprocess(&mut self, _: PipelineId, _: UnprivilegedPipelineContent) { - error!("Multiprocess is not supported on Windows."); - process::exit(1); - } - // Push a new (loading) pipeline to the list of pending frame changes fn push_pending_frame(&mut self, new_pipeline_id: PipelineId, old_pipeline_id: Option<PipelineId>) { diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs index d6d854ef007..330eb345998 100644 --- a/components/constellation/pipeline.rs +++ b/components/constellation/pipeline.rs @@ -8,6 +8,8 @@ use compositing::compositor_thread::Msg as CompositorMsg; use devtools_traits::{DevtoolsControlMsg, ScriptToDevtoolsControlMsg}; use euclid::scale_factor::ScaleFactor; use euclid::size::TypedSize2D; +#[cfg(not(target_os = "windows"))] +use gaol; use gfx::font_cache_thread::FontCacheThread; use gfx::paint_thread::{ChromeToPaintMsg, LayoutToPaintMsg, PaintThread}; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; @@ -25,8 +27,9 @@ use script_traits::{ConstellationControlMsg, InitialScriptState, MozBrowserEvent use script_traits::{LayoutControlMsg, LayoutMsg, NewLayoutInfo, ScriptMsg}; use script_traits::{ScriptThreadFactory, TimerEventRequest}; use std::collections::HashMap; -use std::mem; -use std::sync::mpsc::{Receiver, Sender, channel}; +use std::io::Error as IOError; +use std::process; +use std::sync::mpsc::{Sender, channel}; use url::Url; use util; use util::geometry::{PagePx, ViewportPx}; @@ -35,6 +38,13 @@ use util::opts::{self, Opts}; use util::prefs::{self, Pref}; use webrender_traits; +pub enum ChildProcess { + #[cfg(not(target_os = "windows"))] + Sandboxed(gaol::platform::process::Process), + #[cfg(not(target_os = "windows"))] + Unsandboxed(process::Child), +} + /// A uniquely-identifiable pipeline of script thread, layout thread, and paint thread. pub struct Pipeline { pub id: PipelineId, @@ -109,12 +119,12 @@ pub struct InitialPipelineState { } impl Pipeline { - /// Starts a paint thread, layout thread, and possibly a script thread. - /// Returns the channels wrapped in a struct. - pub fn create<LTF, STF>(state: InitialPipelineState) - -> (Pipeline, UnprivilegedPipelineContent, PrivilegedPipelineContent) - where LTF: LayoutThreadFactory, - STF: ScriptThreadFactory + /// Starts a paint thread, layout thread, and possibly a script thread, in + /// a new process if requested. + pub fn spawn<Message, LTF, STF>(state: InitialPipelineState) + -> Result<(Pipeline, Option<ChildProcess>), IOError> + where LTF: LayoutThreadFactory<Message=Message>, + STF: ScriptThreadFactory<Message=Message> { // Note: we allow channel creation to panic, since recovering from this // probably requires a general low-memory strategy. @@ -127,34 +137,10 @@ impl Pipeline { let (pipeline_chan, pipeline_port) = ipc::channel() .expect("Pipeline main chan");; - let window_size = state.window_size.map(|size| { - WindowSizeData { - visible_viewport: size, - initial_viewport: size * ScaleFactor::new(1.0), - device_pixel_ratio: state.device_pixel_ratio, - } - }); - - // Route messages coming from content to devtools as appropriate. - let script_to_devtools_chan = state.devtools_chan.as_ref().map(|devtools_chan| { - let (script_to_devtools_chan, script_to_devtools_port) = ipc::channel() - .expect("Pipeline script to devtools chan"); - let devtools_chan = (*devtools_chan).clone(); - ROUTER.add_route(script_to_devtools_port.to_opaque(), box move |message| { - match message.to::<ScriptToDevtoolsControlMsg>() { - Err(e) => error!("Cast to ScriptToDevtoolsControlMsg failed ({}).", e), - Ok(message) => if let Err(e) = devtools_chan.send(DevtoolsControlMsg::FromScript(message)) { - warn!("Sending to devtools failed ({})", e) - }, - } - }); - script_to_devtools_chan - }); - let (layout_content_process_shutdown_chan, layout_content_process_shutdown_port) = ipc::channel().expect("Pipeline layout content shutdown chan"); - let (script_chan, script_port, pipeline_port) = match state.script_chan { + let (script_chan, content_ports) = match state.script_chan { Some(script_chan) => { let (containing_pipeline_id, subpage_id, _) = state.parent_info.expect("script_pipeline != None but subpage_id == None"); @@ -174,88 +160,122 @@ impl Pipeline { if let Err(e) = script_chan.send(ConstellationControlMsg::AttachLayout(new_layout_info)) { warn!("Sending to script during pipeline creation failed ({})", e); } - (script_chan, None, None) + (script_chan, None) } None => { let (script_chan, script_port) = ipc::channel().expect("Pipeline script chan"); - (script_chan, Some(script_port), Some(pipeline_port)) + (script_chan, Some((script_port, pipeline_port))) } }; - let (script_content_process_shutdown_chan, script_content_process_shutdown_port) = - ipc::channel().expect("Pipeline script content process shutdown chan"); + PaintThread::create(state.id, + state.load_data.url.clone(), + chrome_to_paint_chan.clone(), + layout_to_paint_port, + chrome_to_paint_port, + state.compositor_proxy.clone_compositor_proxy(), + state.panic_chan.clone(), + state.font_cache_thread.clone(), + state.time_profiler_chan.clone(), + state.mem_profiler_chan.clone(), + paint_shutdown_chan); + + let mut child_process = None; + if let Some((script_port, pipeline_port)) = content_ports { + // Route messages coming from content to devtools as appropriate. + let script_to_devtools_chan = state.devtools_chan.as_ref().map(|devtools_chan| { + let (script_to_devtools_chan, script_to_devtools_port) = ipc::channel() + .expect("Pipeline script to devtools chan"); + let devtools_chan = (*devtools_chan).clone(); + ROUTER.add_route(script_to_devtools_port.to_opaque(), box move |message| { + match message.to::<ScriptToDevtoolsControlMsg>() { + Err(e) => error!("Cast to ScriptToDevtoolsControlMsg failed ({}).", e), + Ok(message) => if let Err(e) = devtools_chan.send(DevtoolsControlMsg::FromScript(message)) { + warn!("Sending to devtools failed ({})", e) + }, + } + }); + script_to_devtools_chan + }); + + let device_pixel_ratio = state.device_pixel_ratio; + let window_size = state.window_size.map(|size| { + WindowSizeData { + visible_viewport: size, + initial_viewport: size * ScaleFactor::new(1.0), + device_pixel_ratio: device_pixel_ratio, + } + }); + + let (script_content_process_shutdown_chan, script_content_process_shutdown_port) = + ipc::channel().expect("Pipeline script content process shutdown chan"); + + let unprivileged_pipeline_content = UnprivilegedPipelineContent { + id: state.id, + parent_info: state.parent_info.map(|(parent_id, subpage_id, _)| (parent_id, subpage_id)), + constellation_chan: state.constellation_chan, + scheduler_chan: state.scheduler_chan, + devtools_chan: script_to_devtools_chan, + bluetooth_thread: state.bluetooth_thread, + image_cache_thread: state.image_cache_thread, + font_cache_thread: state.font_cache_thread, + resource_threads: state.resource_threads, + time_profiler_chan: state.time_profiler_chan, + mem_profiler_chan: state.mem_profiler_chan, + window_size: window_size, + layout_to_constellation_chan: state.layout_to_constellation_chan, + script_chan: script_chan.clone(), + load_data: state.load_data.clone(), + panic_chan: state.panic_chan, + script_port: script_port, + opts: (*opts::get()).clone(), + prefs: prefs::get_cloned(), + layout_to_paint_chan: layout_to_paint_chan, + pipeline_port: pipeline_port, + layout_shutdown_chan: layout_shutdown_chan, + pipeline_namespace_id: state.pipeline_namespace_id, + layout_content_process_shutdown_chan: layout_content_process_shutdown_chan, + layout_content_process_shutdown_port: layout_content_process_shutdown_port, + script_content_process_shutdown_chan: script_content_process_shutdown_chan, + script_content_process_shutdown_port: script_content_process_shutdown_port, + webrender_api_sender: state.webrender_api_sender, + }; + + // Spawn the child process. + // + // Yes, that's all there is to it! + if opts::multiprocess() { + child_process = Some(try!(unprivileged_pipeline_content.spawn_multiprocess())); + } else { + unprivileged_pipeline_content.start_all::<Message, LTF, STF>(false); + } + } let pipeline = Pipeline::new(state.id, state.parent_info, - script_chan.clone(), + script_chan, LayoutControlChan(pipeline_chan), - state.compositor_proxy.clone_compositor_proxy(), - chrome_to_paint_chan.clone(), + state.compositor_proxy, + chrome_to_paint_chan, layout_shutdown_port, paint_shutdown_port, - state.load_data.url.clone(), + state.load_data.url, state.window_size); - let unprivileged_pipeline_content = UnprivilegedPipelineContent { - id: state.id, - parent_info: state.parent_info.map(|(parent_id, subpage_id, _)| (parent_id, subpage_id)), - constellation_chan: state.constellation_chan, - scheduler_chan: state.scheduler_chan, - devtools_chan: script_to_devtools_chan, - bluetooth_thread: state.bluetooth_thread, - image_cache_thread: state.image_cache_thread, - font_cache_thread: state.font_cache_thread.clone(), - resource_threads: state.resource_threads, - time_profiler_chan: state.time_profiler_chan.clone(), - mem_profiler_chan: state.mem_profiler_chan.clone(), - window_size: window_size, - layout_to_constellation_chan: state.layout_to_constellation_chan, - script_chan: script_chan, - load_data: state.load_data.clone(), - panic_chan: state.panic_chan.clone(), - script_port: script_port, - opts: (*opts::get()).clone(), - prefs: prefs::get_cloned(), - layout_to_paint_chan: layout_to_paint_chan, - pipeline_port: pipeline_port, - layout_shutdown_chan: layout_shutdown_chan, - paint_shutdown_chan: paint_shutdown_chan.clone(), - pipeline_namespace_id: state.pipeline_namespace_id, - layout_content_process_shutdown_chan: layout_content_process_shutdown_chan, - layout_content_process_shutdown_port: layout_content_process_shutdown_port, - script_content_process_shutdown_chan: script_content_process_shutdown_chan, - script_content_process_shutdown_port: script_content_process_shutdown_port, - webrender_api_sender: state.webrender_api_sender, - }; - - let privileged_pipeline_content = PrivilegedPipelineContent { - id: state.id, - compositor_proxy: state.compositor_proxy, - font_cache_thread: state.font_cache_thread, - time_profiler_chan: state.time_profiler_chan, - mem_profiler_chan: state.mem_profiler_chan, - load_data: state.load_data, - panic_chan: state.panic_chan, - layout_to_paint_port: layout_to_paint_port, - chrome_to_paint_chan: chrome_to_paint_chan, - chrome_to_paint_port: chrome_to_paint_port, - paint_shutdown_chan: paint_shutdown_chan, - }; - - (pipeline, unprivileged_pipeline_content, privileged_pipeline_content) + Ok((pipeline, child_process)) } - pub fn new(id: PipelineId, - parent_info: Option<(PipelineId, SubpageId, FrameType)>, - script_chan: IpcSender<ConstellationControlMsg>, - layout_chan: LayoutControlChan, - compositor_proxy: Box<CompositorProxy + 'static + Send>, - chrome_to_paint_chan: Sender<ChromeToPaintMsg>, - layout_shutdown_port: IpcReceiver<()>, - paint_shutdown_port: IpcReceiver<()>, - url: Url, - size: Option<TypedSize2D<PagePx, f32>>) - -> Pipeline { + fn new(id: PipelineId, + parent_info: Option<(PipelineId, SubpageId, FrameType)>, + script_chan: IpcSender<ConstellationControlMsg>, + layout_chan: LayoutControlChan, + compositor_proxy: Box<CompositorProxy + 'static + Send>, + chrome_to_paint_chan: Sender<ChromeToPaintMsg>, + layout_shutdown_port: IpcReceiver<()>, + paint_shutdown_port: IpcReceiver<()>, + url: Url, + size: Option<TypedSize2D<PagePx, f32>>) + -> Pipeline { Pipeline { id: id, parent_info: parent_info, @@ -385,12 +405,11 @@ pub struct UnprivilegedPipelineContent { script_chan: IpcSender<ConstellationControlMsg>, load_data: LoadData, panic_chan: IpcSender<PanicMsg>, - script_port: Option<IpcReceiver<ConstellationControlMsg>>, + script_port: IpcReceiver<ConstellationControlMsg>, layout_to_paint_chan: OptionalIpcSender<LayoutToPaintMsg>, opts: Opts, prefs: HashMap<String, Pref>, - paint_shutdown_chan: IpcSender<()>, - pipeline_port: Option<IpcReceiver<LayoutControlMsg>>, + pipeline_port: IpcReceiver<LayoutControlMsg>, pipeline_namespace_id: PipelineNamespaceId, layout_shutdown_chan: IpcSender<()>, layout_content_process_shutdown_chan: IpcSender<()>, @@ -401,7 +420,7 @@ pub struct UnprivilegedPipelineContent { } impl UnprivilegedPipelineContent { - pub fn start_all<Message, LTF, STF>(mut self, wait_for_completion: bool) + pub fn start_all<Message, LTF, STF>(self, wait_for_completion: bool) where LTF: LayoutThreadFactory<Message=Message>, STF: ScriptThreadFactory<Message=Message> { @@ -409,11 +428,11 @@ impl UnprivilegedPipelineContent { id: self.id, parent_info: self.parent_info, control_chan: self.script_chan.clone(), - control_port: mem::replace(&mut self.script_port, None).expect("No script port."), - constellation_chan: self.constellation_chan.clone(), - scheduler_chan: self.scheduler_chan.clone(), + control_port: self.script_port, + constellation_chan: self.constellation_chan, + scheduler_chan: self.scheduler_chan, panic_chan: self.panic_chan.clone(), - bluetooth_thread: self.bluetooth_thread.clone(), + bluetooth_thread: self.bluetooth_thread, resource_threads: self.resource_threads, image_cache_thread: self.image_cache_thread.clone(), time_profiler_chan: self.time_profiler_chan.clone(), @@ -421,24 +440,24 @@ impl UnprivilegedPipelineContent { devtools_chan: self.devtools_chan, window_size: self.window_size, pipeline_namespace_id: self.pipeline_namespace_id, - content_process_shutdown_chan: self.script_content_process_shutdown_chan.clone(), + content_process_shutdown_chan: self.script_content_process_shutdown_chan, }, self.load_data.clone()); LTF::create(self.id, - self.load_data.url.clone(), + self.load_data.url, self.parent_info.is_some(), layout_pair, - self.pipeline_port.expect("No pipeline port."), + self.pipeline_port, self.layout_to_constellation_chan, self.panic_chan, - self.script_chan.clone(), - self.layout_to_paint_chan.clone(), + self.script_chan, + self.layout_to_paint_chan, self.image_cache_thread, self.font_cache_thread, self.time_profiler_chan, self.mem_profiler_chan, self.layout_shutdown_chan, - self.layout_content_process_shutdown_chan.clone(), + self.layout_content_process_shutdown_chan, self.webrender_api_sender); if wait_for_completion { @@ -447,6 +466,59 @@ impl UnprivilegedPipelineContent { } } + #[cfg(not(target_os = "windows"))] + pub fn spawn_multiprocess(self) -> Result<ChildProcess, IOError> { + use gaol::sandbox::{self, Sandbox, SandboxMethods}; + use ipc_channel::ipc::IpcOneShotServer; + use sandboxing::content_process_sandbox_profile; + use std::env; + + // Note that this function can panic, due to process creation, + // avoiding this panic would require a mechanism for dealing + // with low-resource scenarios. + let (server, token) = + IpcOneShotServer::<IpcSender<UnprivilegedPipelineContent>>::new() + .expect("Failed to create IPC one-shot server."); + + // If there is a sandbox, use the `gaol` API to create the child process. + let child_process = if opts::get().sandbox { + let mut command = sandbox::Command::me().expect("Failed to get current sandbox."); + command.arg("--content-process").arg(token); + + if let Ok(value) = env::var("RUST_BACKTRACE") { + command.env("RUST_BACKTRACE", value); + } + + let profile = content_process_sandbox_profile(); + ChildProcess::Sandboxed(Sandbox::new(profile).start(&mut command) + .expect("Failed to start sandboxed child process!")) + } else { + let path_to_self = env::current_exe() + .expect("Failed to get current executor."); + let mut child_process = process::Command::new(path_to_self); + child_process.arg("--content-process"); + child_process.arg(token); + + if let Ok(value) = env::var("RUST_BACKTRACE") { + child_process.env("RUST_BACKTRACE", value); + } + + ChildProcess::Unsandboxed(child_process.spawn() + .expect("Failed to start unsandboxed child process!")) + }; + + let (_receiver, sender) = server.accept().expect("Server failed to accept."); + try!(sender.send(self)); + + Ok(child_process) + } + + #[cfg(target_os = "windows")] + pub fn spawn_multiprocess(self) -> Result<ChildProcess, IOError> { + error!("Multiprocess is not supported on Windows."); + process::exit(1); + } + pub fn opts(&self) -> Opts { self.opts.clone() } @@ -455,34 +527,3 @@ impl UnprivilegedPipelineContent { self.prefs.clone() } } - -pub struct PrivilegedPipelineContent { - id: PipelineId, - compositor_proxy: Box<CompositorProxy + Send + 'static>, - font_cache_thread: FontCacheThread, - time_profiler_chan: time::ProfilerChan, - mem_profiler_chan: profile_mem::ProfilerChan, - load_data: LoadData, - panic_chan: IpcSender<PanicMsg>, - layout_to_paint_port: Receiver<LayoutToPaintMsg>, - chrome_to_paint_chan: Sender<ChromeToPaintMsg>, - chrome_to_paint_port: Receiver<ChromeToPaintMsg>, - paint_shutdown_chan: IpcSender<()>, -} - -impl PrivilegedPipelineContent { - pub fn start(self) { - PaintThread::create(self.id, - self.load_data.url, - self.chrome_to_paint_chan, - self.layout_to_paint_port, - self.chrome_to_paint_port, - self.compositor_proxy, - self.panic_chan, - self.font_cache_thread, - self.time_profiler_chan, - self.mem_profiler_chan, - self.paint_shutdown_chan); - - } -} |