From 82832f134be329071667c3f825cec34ee281e4df Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Thu, 26 May 2016 09:41:55 +0200 Subject: [PATCH] Move spawn_multiprocess into UnprivilegedPipelineContent. --- components/constellation/constellation.rs | 76 ++--------------------- components/constellation/pipeline.rs | 64 +++++++++++++++++++ 2 files changed, 69 insertions(+), 71 deletions(-) diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index d183b95b7ff..aafe234896d 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; @@ -312,13 +302,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 Constellation where LTF: LayoutThreadFactory, STF: ScriptThreadFactory @@ -455,7 +438,10 @@ impl Constellation // // Yes, that's all there is to it! if opts::multiprocess() { - self.spawn_multiprocess(pipeline_id, unprivileged_pipeline_content); + match unprivileged_pipeline_content.spawn_multiprocess() { + Ok(child_process) => self.child_processes.push(child_process), + Err(e) => self.handle_send_error(pipeline_id, e), + } } else { unprivileged_pipeline_content.start_all::(false); } @@ -465,58 +451,6 @@ impl Constellation 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::>::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) { diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs index 762a34c25e0..0e6acf571d4 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,7 +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::io::Error as IOError; use std::mem; +use std::process; use std::sync::mpsc::{Receiver, Sender, channel}; use url::Url; use util; @@ -35,6 +39,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, @@ -447,6 +458,59 @@ impl UnprivilegedPipelineContent { } } + #[cfg(not(target_os = "windows"))] + pub fn spawn_multiprocess(self) -> Result { + 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::>::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 { + error!("Multiprocess is not supported on Windows."); + process::exit(1); + } + pub fn opts(&self) -> Opts { self.opts.clone() }