mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
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:
commit
01b6ad55bd
2 changed files with 24 additions and 47 deletions
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue