Auto merge of #14536 - frewsxcv:constellation-child-processes, r=jdm

Remove `Constellation::child_processes`.

Fixes https://github.com/servo/servo/issues/11459.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14536)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-12-14 10:52:54 -08:00 committed by GitHub
commit 01b6ad55bd
2 changed files with 24 additions and 47 deletions

View file

@ -35,7 +35,7 @@ use net_traits::image_cache_thread::ImageCacheThread;
use net_traits::pub_domains::reg_suffix; use net_traits::pub_domains::reg_suffix;
use net_traits::storage_thread::{StorageThreadMsg, StorageType}; use net_traits::storage_thread::{StorageThreadMsg, StorageType};
use offscreen_gl_context::{GLContextAttributes, GLLimits}; use offscreen_gl_context::{GLContextAttributes, GLLimits};
use pipeline::{ChildProcess, InitialPipelineState, Pipeline}; use pipeline::{InitialPipelineState, Pipeline};
use profile_traits::mem; use profile_traits::mem;
use profile_traits::time; use profile_traits::time;
use rand::{Rng, SeedableRng, StdRng, random}; use rand::{Rng, SeedableRng, StdRng, random};
@ -175,10 +175,6 @@ pub struct Constellation<Message, LTF, STF> {
scheduler_chan: IpcSender<TimerEventRequest>, scheduler_chan: IpcSender<TimerEventRequest>,
/// A list of child content processes.
#[cfg_attr(target_os = "windows", allow(dead_code))]
child_processes: Vec<ChildProcess>,
/// Document states for loaded pipelines (used only when writing screenshots). /// Document states for loaded pipelines (used only when writing screenshots).
document_states: HashMap<PipelineId, DocumentState>, document_states: HashMap<PipelineId, DocumentState>,
@ -558,7 +554,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
phantom: PhantomData, phantom: PhantomData,
webdriver: WebDriverData::new(), webdriver: WebDriverData::new(),
scheduler_chan: TimerScheduler::start(), scheduler_chan: TimerScheduler::start(),
child_processes: Vec::new(),
document_states: HashMap::new(), document_states: HashMap::new(),
webrender_api_sender: state.webrender_api_sender, webrender_api_sender: state.webrender_api_sender,
shutting_down: false, shutting_down: false,
@ -679,15 +674,11 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
is_private: is_private, is_private: is_private,
}); });
let (pipeline, child_process) = match result { let pipeline = match result {
Ok(result) => result, Ok(result) => result,
Err(e) => return self.handle_send_error(pipeline_id, e), Err(e) => return self.handle_send_error(pipeline_id, e),
}; };
if let Some(child_process) = child_process {
self.child_processes.push(child_process);
}
if let Some(host) = host { if let Some(host) = host {
self.script_channels.entry(top_level_frame_id) self.script_channels.entry(top_level_frame_id)
.or_insert_with(HashMap::new) .or_insert_with(HashMap::new)

View file

@ -10,8 +10,6 @@ use constellation::ScriptChan;
use devtools_traits::{DevtoolsControlMsg, ScriptToDevtoolsControlMsg}; use devtools_traits::{DevtoolsControlMsg, ScriptToDevtoolsControlMsg};
use euclid::scale_factor::ScaleFactor; use euclid::scale_factor::ScaleFactor;
use euclid::size::TypedSize2D; use euclid::size::TypedSize2D;
#[cfg(not(target_os = "windows"))]
use gaol;
use gfx::font_cache_thread::FontCacheThread; use gfx::font_cache_thread::FontCacheThread;
use gfx_traits::DevicePixel; use gfx_traits::DevicePixel;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
@ -39,13 +37,6 @@ use util::opts::{self, Opts};
use util::prefs::{PREFS, Pref}; use util::prefs::{PREFS, Pref};
use webrender_traits; 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. /// A uniquely-identifiable pipeline of script thread, layout thread, and paint thread.
pub struct Pipeline { pub struct Pipeline {
pub id: PipelineId, pub id: PipelineId,
@ -134,15 +125,14 @@ pub struct InitialPipelineState {
impl Pipeline { impl Pipeline {
/// Starts a paint thread, layout thread, and possibly a script thread, in /// Starts a paint thread, layout thread, and possibly a script thread, in
/// a new process if requested. /// a new process if requested.
pub fn spawn<Message, LTF, STF>(state: InitialPipelineState) pub fn spawn<Message, LTF, STF>(state: InitialPipelineState) -> Result<Pipeline, IOError>
-> Result<(Pipeline, Option<ChildProcess>), IOError>
where LTF: LayoutThreadFactory<Message=Message>, where LTF: LayoutThreadFactory<Message=Message>,
STF: ScriptThreadFactory<Message=Message> STF: ScriptThreadFactory<Message=Message>
{ {
// Note: we allow channel creation to panic, since recovering from this // Note: we allow channel creation to panic, since recovering from this
// probably requires a general low-memory strategy. // probably requires a general low-memory strategy.
let (pipeline_chan, pipeline_port) = ipc::channel() let (pipeline_chan, pipeline_port) = ipc::channel()
.expect("Pipeline main chan");; .expect("Pipeline main chan");
let (layout_content_process_shutdown_chan, layout_content_process_shutdown_port) = let (layout_content_process_shutdown_chan, layout_content_process_shutdown_port) =
ipc::channel().expect("Pipeline layout content shutdown chan"); ipc::channel().expect("Pipeline layout content shutdown chan");
@ -180,7 +170,6 @@ impl Pipeline {
} }
}; };
let mut child_process = None;
if let Some((script_port, pipeline_port)) = content_ports { if let Some((script_port, pipeline_port)) = content_ports {
// Route messages coming from content to devtools as appropriate. // 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 = state.devtools_chan.as_ref().map(|devtools_chan| {
@ -236,24 +225,22 @@ impl Pipeline {
// //
// Yes, that's all there is to it! // Yes, that's all there is to it!
if opts::multiprocess() { if opts::multiprocess() {
child_process = Some(try!(unprivileged_pipeline_content.spawn_multiprocess())); let _ = try!(unprivileged_pipeline_content.spawn_multiprocess());
} else { } else {
unprivileged_pipeline_content.start_all::<Message, LTF, STF>(false); unprivileged_pipeline_content.start_all::<Message, LTF, STF>(false);
} }
} }
let pipeline = Pipeline::new(state.id, Ok(Pipeline::new(state.id,
state.frame_id, state.frame_id,
state.parent_info, state.parent_info,
script_chan, script_chan,
pipeline_chan, pipeline_chan,
state.compositor_proxy, state.compositor_proxy,
state.is_private, state.is_private,
state.load_data.url, state.load_data.url,
state.window_size, state.window_size,
state.prev_visibility.unwrap_or(true)); state.prev_visibility.unwrap_or(true)))
Ok((pipeline, child_process))
} }
/// Creates a new `Pipeline`, after the script and layout threads have been /// Creates a new `Pipeline`, after the script and layout threads have been
@ -464,7 +451,7 @@ impl UnprivilegedPipelineContent {
} }
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
pub fn spawn_multiprocess(self) -> Result<ChildProcess, IOError> { pub fn spawn_multiprocess(self) -> Result<(), IOError> {
use gaol::sandbox::{self, Sandbox, SandboxMethods}; use gaol::sandbox::{self, Sandbox, SandboxMethods};
use ipc_channel::ipc::IpcOneShotServer; use ipc_channel::ipc::IpcOneShotServer;
use sandboxing::content_process_sandbox_profile; use sandboxing::content_process_sandbox_profile;
@ -489,31 +476,30 @@ impl UnprivilegedPipelineContent {
.expect("Failed to create IPC one-shot server."); .expect("Failed to create IPC one-shot server.");
// If there is a sandbox, use the `gaol` API to create the child process. // If there is a sandbox, use the `gaol` API to create the child process.
let child_process = if opts::get().sandbox { if opts::get().sandbox {
let mut command = sandbox::Command::me().expect("Failed to get current sandbox."); let mut command = sandbox::Command::me().expect("Failed to get current sandbox.");
self.setup_common(&mut command, token); self.setup_common(&mut command, token);
let profile = content_process_sandbox_profile(); let profile = content_process_sandbox_profile();
ChildProcess::Sandboxed(Sandbox::new(profile).start(&mut command) let _ = Sandbox::new(profile)
.expect("Failed to start sandboxed child process!")) .start(&mut command)
.expect("Failed to start sandboxed child process!");
} else { } else {
let path_to_self = env::current_exe() let path_to_self = env::current_exe()
.expect("Failed to get current executor."); .expect("Failed to get current executor.");
let mut child_process = process::Command::new(path_to_self); let mut child_process = process::Command::new(path_to_self);
self.setup_common(&mut child_process, token); self.setup_common(&mut child_process, token);
let _ = child_process.spawn().expect("Failed to start unsandboxed child process!");
ChildProcess::Unsandboxed(child_process.spawn() }
.expect("Failed to start unsandboxed child process!"))
};
let (_receiver, sender) = server.accept().expect("Server failed to accept."); let (_receiver, sender) = server.accept().expect("Server failed to accept.");
try!(sender.send(self)); try!(sender.send(self));
Ok(child_process) Ok(())
} }
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
pub fn spawn_multiprocess(self) -> Result<ChildProcess, IOError> { pub fn spawn_multiprocess(self) -> Result<(), IOError> {
error!("Multiprocess is not supported on Windows."); error!("Multiprocess is not supported on Windows.");
process::exit(1); process::exit(1);
} }