mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Auto merge of #8599 - jdm:e10s-redux, r=metajack
compositing: Split Servo up into multiple sandboxed processes. Multiprocess mode is enabled with the `-M` switch, and sandboxing is enabled with the `-S` switch. Rebase of #6884. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/8599) <!-- Reviewable:end -->
This commit is contained in:
commit
8b39b9afed
33 changed files with 688 additions and 265 deletions
|
@ -68,14 +68,20 @@ features = ["texture_surface"]
|
||||||
version = "0.2"
|
version = "0.2"
|
||||||
features = [ "serde_serialization" ]
|
features = [ "serde_serialization" ]
|
||||||
|
|
||||||
|
[dependencies.gaol]
|
||||||
|
git = "https://github.com/pcwalton/gaol"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
app_units = {version = "0.1", features = ["plugins"]}
|
app_units = {version = "0.1", features = ["plugins"]}
|
||||||
image = "0.4.0"
|
image = "0.4.0"
|
||||||
|
libc = "0.1"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
num = "0.1.24"
|
num = "0.1.24"
|
||||||
time = "0.1.17"
|
time = "0.1.17"
|
||||||
gleam = "0.1"
|
gleam = "0.1"
|
||||||
euclid = {version = "0.3", features = ["plugins"]}
|
euclid = {version = "0.3", features = ["plugins"]}
|
||||||
|
serde = "0.6"
|
||||||
|
serde_macros = "0.6"
|
||||||
|
|
||||||
[target.x86_64-apple-darwin.dependencies]
|
[target.x86_64-apple-darwin.dependencies]
|
||||||
core-graphics = "0.1"
|
core-graphics = "0.1"
|
||||||
|
|
|
@ -17,7 +17,7 @@ use gfx_traits::color;
|
||||||
use gleam::gl;
|
use gleam::gl;
|
||||||
use gleam::gl::types::{GLint, GLsizei};
|
use gleam::gl::types::{GLint, GLsizei};
|
||||||
use image::{DynamicImage, ImageFormat, RgbImage};
|
use image::{DynamicImage, ImageFormat, RgbImage};
|
||||||
use ipc_channel::ipc::{self, IpcSharedMemory};
|
use ipc_channel::ipc::{self, IpcSender, IpcSharedMemory};
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
use layers::geometry::{DevicePixel, LayerPixel};
|
use layers::geometry::{DevicePixel, LayerPixel};
|
||||||
use layers::layers::{BufferRequest, Layer, LayerBuffer, LayerBufferSet};
|
use layers::layers::{BufferRequest, Layer, LayerBuffer, LayerBufferSet};
|
||||||
|
@ -30,7 +30,7 @@ use msg::compositor_msg::{Epoch, EventResult, FrameTreeId, LayerId, LayerKind};
|
||||||
use msg::compositor_msg::{LayerProperties, ScrollPolicy};
|
use msg::compositor_msg::{LayerProperties, ScrollPolicy};
|
||||||
use msg::constellation_msg::CompositorMsg as ConstellationMsg;
|
use msg::constellation_msg::CompositorMsg as ConstellationMsg;
|
||||||
use msg::constellation_msg::{AnimationState, Image, PixelFormat};
|
use msg::constellation_msg::{AnimationState, Image, PixelFormat};
|
||||||
use msg::constellation_msg::{ConstellationChan, Key, KeyModifiers, KeyState, LoadData};
|
use msg::constellation_msg::{Key, KeyModifiers, KeyState, LoadData};
|
||||||
use msg::constellation_msg::{NavigationDirection, PipelineId, WindowSizeData};
|
use msg::constellation_msg::{NavigationDirection, PipelineId, WindowSizeData};
|
||||||
use pipeline::CompositionPipeline;
|
use pipeline::CompositionPipeline;
|
||||||
use profile_traits::mem::{self, ReportKind, Reporter, ReporterRequest};
|
use profile_traits::mem::{self, ReportKind, Reporter, ReporterRequest};
|
||||||
|
@ -168,7 +168,7 @@ pub struct IOCompositor<Window: WindowMethods> {
|
||||||
frame_tree_id: FrameTreeId,
|
frame_tree_id: FrameTreeId,
|
||||||
|
|
||||||
/// The channel on which messages can be sent to the constellation.
|
/// The channel on which messages can be sent to the constellation.
|
||||||
constellation_chan: ConstellationChan<ConstellationMsg>,
|
constellation_chan: Sender<ConstellationMsg>,
|
||||||
|
|
||||||
/// The channel on which messages can be sent to the time profiler.
|
/// The channel on which messages can be sent to the time profiler.
|
||||||
time_profiler_chan: time::ProfilerChan,
|
time_profiler_chan: time::ProfilerChan,
|
||||||
|
@ -385,8 +385,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
|
|
||||||
pub fn start_shutting_down(&mut self) {
|
pub fn start_shutting_down(&mut self) {
|
||||||
debug!("Compositor sending Exit message to Constellation");
|
debug!("Compositor sending Exit message to Constellation");
|
||||||
let ConstellationChan(ref constellation_channel) = self.constellation_chan;
|
self.constellation_chan.send(ConstellationMsg::Exit).unwrap();
|
||||||
constellation_channel.send(ConstellationMsg::Exit).unwrap();
|
|
||||||
|
|
||||||
self.mem_profiler_chan.send(mem::ProfilerMsg::UnregisterReporter(reporter_name()));
|
self.mem_profiler_chan.send(mem::ProfilerMsg::UnregisterReporter(reporter_name()));
|
||||||
|
|
||||||
|
@ -702,8 +701,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
|
|
||||||
fn set_frame_tree(&mut self,
|
fn set_frame_tree(&mut self,
|
||||||
frame_tree: &SendableFrameTree,
|
frame_tree: &SendableFrameTree,
|
||||||
response_chan: Sender<()>,
|
response_chan: IpcSender<()>,
|
||||||
new_constellation_chan: ConstellationChan<ConstellationMsg>) {
|
new_constellation_chan: Sender<ConstellationMsg>) {
|
||||||
response_chan.send(()).unwrap();
|
response_chan.send(()).unwrap();
|
||||||
|
|
||||||
// There are now no more pending iframes.
|
// There are now no more pending iframes.
|
||||||
|
@ -943,8 +942,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
let initial_viewport = self.window_size.as_f32() / dppx;
|
let initial_viewport = self.window_size.as_f32() / dppx;
|
||||||
let visible_viewport = initial_viewport / self.viewport_zoom;
|
let visible_viewport = initial_viewport / self.viewport_zoom;
|
||||||
|
|
||||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
self.constellation_chan.send(ConstellationMsg::ResizedWindow(WindowSizeData {
|
||||||
chan.send(ConstellationMsg::ResizedWindow(WindowSizeData {
|
|
||||||
device_pixel_ratio: dppx,
|
device_pixel_ratio: dppx,
|
||||||
initial_viewport: initial_viewport,
|
initial_viewport: initial_viewport,
|
||||||
visible_viewport: visible_viewport,
|
visible_viewport: visible_viewport,
|
||||||
|
@ -959,9 +957,9 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
self.constellation_chan.send(ConstellationMsg::FrameSize(
|
||||||
chan.send(ConstellationMsg::FrameSize(*subpage_pipeline_id,
|
*subpage_pipeline_id,
|
||||||
layer_properties.rect.size)).unwrap();
|
layer_properties.rect.size)).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_layer(&self,
|
pub fn move_layer(&self,
|
||||||
|
@ -1168,8 +1166,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
None => ConstellationMsg::InitLoadUrl(url)
|
None => ConstellationMsg::InitLoadUrl(url)
|
||||||
};
|
};
|
||||||
|
|
||||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
self.constellation_chan.send(msg).unwrap()
|
||||||
chan.send(msg).unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_mouse_window_event_class(&mut self, mouse_window_event: MouseWindowEvent) {
|
fn on_mouse_window_event_class(&mut self, mouse_window_event: MouseWindowEvent) {
|
||||||
|
@ -1446,7 +1443,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tick_animations_for_pipeline(&self, pipeline_id: PipelineId) {
|
fn tick_animations_for_pipeline(&self, pipeline_id: PipelineId) {
|
||||||
self.constellation_chan.0.send(ConstellationMsg::TickAnimation(pipeline_id)).unwrap()
|
self.constellation_chan.send(ConstellationMsg::TickAnimation(pipeline_id)).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn constrain_viewport(&mut self, pipeline_id: PipelineId, constraints: ViewportConstraints) {
|
fn constrain_viewport(&mut self, pipeline_id: PipelineId, constraints: ViewportConstraints) {
|
||||||
|
@ -1538,13 +1535,11 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
windowing::WindowNavigateMsg::Forward => NavigationDirection::Forward,
|
windowing::WindowNavigateMsg::Forward => NavigationDirection::Forward,
|
||||||
windowing::WindowNavigateMsg::Back => NavigationDirection::Back,
|
windowing::WindowNavigateMsg::Back => NavigationDirection::Back,
|
||||||
};
|
};
|
||||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
self.constellation_chan.send(ConstellationMsg::Navigate(None, direction)).unwrap()
|
||||||
chan.send(ConstellationMsg::Navigate(None, direction)).unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_key_event(&self, key: Key, state: KeyState, modifiers: KeyModifiers) {
|
fn on_key_event(&self, key: Key, state: KeyState, modifiers: KeyModifiers) {
|
||||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
self.constellation_chan.send(ConstellationMsg::KeyEvent(key, state, modifiers)).unwrap()
|
||||||
chan.send(ConstellationMsg::KeyEvent(key, state, modifiers)).unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fill_paint_request_with_cached_layer_buffers(&mut self, paint_request: &mut PaintRequest) {
|
fn fill_paint_request_with_cached_layer_buffers(&mut self, paint_request: &mut PaintRequest) {
|
||||||
|
@ -1744,8 +1739,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
|
|
||||||
// Pass the pipeline/epoch states to the constellation and check
|
// Pass the pipeline/epoch states to the constellation and check
|
||||||
// if it's safe to output the image.
|
// if it's safe to output the image.
|
||||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
self.constellation_chan.send(ConstellationMsg::IsReadyToSaveImage(pipeline_epochs)).unwrap();
|
||||||
chan.send(ConstellationMsg::IsReadyToSaveImage(pipeline_epochs)).unwrap();
|
|
||||||
self.ready_to_save_state = ReadyState::WaitingForConstellationReply;
|
self.ready_to_save_state = ReadyState::WaitingForConstellationReply;
|
||||||
Err(NotReadyToPaint::JustNotifiedConstellation)
|
Err(NotReadyToPaint::JustNotifiedConstellation)
|
||||||
}
|
}
|
||||||
|
@ -2167,8 +2161,7 @@ impl<Window> CompositorEventListener for IOCompositor<Window> where Window: Wind
|
||||||
None => return,
|
None => return,
|
||||||
Some(ref root_pipeline) => root_pipeline.id,
|
Some(ref root_pipeline) => root_pipeline.id,
|
||||||
};
|
};
|
||||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
self.constellation_chan.send(ConstellationMsg::GetPipelineTitle(root_pipeline_id)).unwrap();
|
||||||
chan.send(ConstellationMsg::GetPipelineTitle(root_pipeline_id)).unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,15 +5,16 @@
|
||||||
//! Communication with the compositor task.
|
//! Communication with the compositor task.
|
||||||
|
|
||||||
use compositor;
|
use compositor;
|
||||||
use euclid::{Point2D, Size2D};
|
use euclid::point::Point2D;
|
||||||
|
use euclid::size::Size2D;
|
||||||
use headless;
|
use headless;
|
||||||
use ipc_channel::ipc::{IpcReceiver, IpcSender};
|
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||||
use layers::layers::{BufferRequest, LayerBufferSet};
|
use layers::layers::{BufferRequest, LayerBufferSet};
|
||||||
use layers::platform::surface::{NativeDisplay, NativeSurface};
|
use layers::platform::surface::{NativeDisplay, NativeSurface};
|
||||||
use msg::compositor_msg::{Epoch, EventResult, FrameTreeId, LayerId, LayerProperties};
|
use msg::compositor_msg::{Epoch, EventResult, FrameTreeId, LayerId, LayerProperties};
|
||||||
use msg::compositor_msg::{PaintListener, ScriptToCompositorMsg};
|
use msg::compositor_msg::{PaintListener, ScriptToCompositorMsg};
|
||||||
use msg::constellation_msg::CompositorMsg as ConstellationMsg;
|
use msg::constellation_msg::CompositorMsg as ConstellationMsg;
|
||||||
use msg::constellation_msg::{AnimationState, ConstellationChan, PipelineId};
|
use msg::constellation_msg::{AnimationState, PipelineId};
|
||||||
use msg::constellation_msg::{Image, Key, KeyModifiers, KeyState};
|
use msg::constellation_msg::{Image, Key, KeyModifiers, KeyState};
|
||||||
use profile_traits::mem;
|
use profile_traits::mem;
|
||||||
use profile_traits::time;
|
use profile_traits::time;
|
||||||
|
@ -60,11 +61,11 @@ pub fn run_script_listener_thread(compositor_proxy: Box<CompositorProxy + 'stati
|
||||||
receiver: IpcReceiver<ScriptToCompositorMsg>) {
|
receiver: IpcReceiver<ScriptToCompositorMsg>) {
|
||||||
while let Ok(msg) = receiver.recv() {
|
while let Ok(msg) = receiver.recv() {
|
||||||
match msg {
|
match msg {
|
||||||
ScriptToCompositorMsg::ScrollFragmentPoint(pipeline_id, layer_id, point, _smooth) => {
|
ScriptToCompositorMsg::ScrollFragmentPoint(pipeline_id, layer_id, point, smooth) => {
|
||||||
compositor_proxy.send(Msg::ScrollFragmentPoint(pipeline_id,
|
compositor_proxy.send(Msg::ScrollFragmentPoint(pipeline_id,
|
||||||
layer_id,
|
layer_id,
|
||||||
point,
|
point,
|
||||||
_smooth));
|
smooth));
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptToCompositorMsg::GetClientWindow(send) => {
|
ScriptToCompositorMsg::GetClientWindow(send) => {
|
||||||
|
@ -80,7 +81,7 @@ pub fn run_script_listener_thread(compositor_proxy: Box<CompositorProxy + 'stati
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptToCompositorMsg::Exit => {
|
ScriptToCompositorMsg::Exit => {
|
||||||
let (chan, port) = channel();
|
let (chan, port) = ipc::channel().unwrap();
|
||||||
compositor_proxy.send(Msg::Exit(chan));
|
compositor_proxy.send(Msg::Exit(chan));
|
||||||
port.recv().unwrap();
|
port.recv().unwrap();
|
||||||
}
|
}
|
||||||
|
@ -152,7 +153,7 @@ impl PaintListener for Box<CompositorProxy + 'static + Send> {
|
||||||
/// Messages from the painting task and the constellation task to the compositor task.
|
/// Messages from the painting task and the constellation task to the compositor task.
|
||||||
pub enum Msg {
|
pub enum Msg {
|
||||||
/// Requests that the compositor shut down.
|
/// Requests that the compositor shut down.
|
||||||
Exit(Sender<()>),
|
Exit(IpcSender<()>),
|
||||||
|
|
||||||
/// Informs the compositor that the constellation has completed shutdown.
|
/// Informs the compositor that the constellation has completed shutdown.
|
||||||
/// Required because the constellation can have pending calls to make
|
/// Required because the constellation can have pending calls to make
|
||||||
|
@ -180,7 +181,7 @@ pub enum Msg {
|
||||||
/// Alerts the compositor that the given pipeline has changed whether it is running animations.
|
/// Alerts the compositor that the given pipeline has changed whether it is running animations.
|
||||||
ChangeRunningAnimationsState(PipelineId, AnimationState),
|
ChangeRunningAnimationsState(PipelineId, AnimationState),
|
||||||
/// Replaces the current frame tree, typically called during main frame navigation.
|
/// Replaces the current frame tree, typically called during main frame navigation.
|
||||||
SetFrameTree(SendableFrameTree, Sender<()>, ConstellationChan<ConstellationMsg>),
|
SetFrameTree(SendableFrameTree, IpcSender<()>, Sender<ConstellationMsg>),
|
||||||
/// The load of a page has begun: (can go back, can go forward).
|
/// The load of a page has begun: (can go back, can go forward).
|
||||||
LoadStart(bool, bool),
|
LoadStart(bool, bool),
|
||||||
/// The load of a page has completed: (can go back, can go forward).
|
/// The load of a page has completed: (can go back, can go forward).
|
||||||
|
@ -296,7 +297,7 @@ pub struct InitialCompositorState {
|
||||||
/// A port on which messages inbound to the compositor can be received.
|
/// A port on which messages inbound to the compositor can be received.
|
||||||
pub receiver: Box<CompositorReceiver>,
|
pub receiver: Box<CompositorReceiver>,
|
||||||
/// A channel to the constellation.
|
/// A channel to the constellation.
|
||||||
pub constellation_chan: ConstellationChan<ConstellationMsg>,
|
pub constellation_chan: Sender<ConstellationMsg>,
|
||||||
/// A channel to the time profiler thread.
|
/// A channel to the time profiler thread.
|
||||||
pub time_profiler_chan: time::ProfilerChan,
|
pub time_profiler_chan: time::ProfilerChan,
|
||||||
/// A channel to the memory profiler thread.
|
/// A channel to the memory profiler thread.
|
||||||
|
|
|
@ -18,8 +18,11 @@ use compositor_task::Msg as ToCompositorMsg;
|
||||||
use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg};
|
use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg};
|
||||||
use euclid::scale_factor::ScaleFactor;
|
use euclid::scale_factor::ScaleFactor;
|
||||||
use euclid::size::{Size2D, TypedSize2D};
|
use euclid::size::{Size2D, TypedSize2D};
|
||||||
|
use gaol;
|
||||||
|
use gaol::sandbox::{self, Sandbox, SandboxMethods};
|
||||||
use gfx::font_cache_task::FontCacheTask;
|
use gfx::font_cache_task::FontCacheTask;
|
||||||
use ipc_channel::ipc::{self, IpcSender};
|
use ipc_channel::ipc::{self, IpcOneShotServer, IpcSender};
|
||||||
|
use ipc_channel::router::ROUTER;
|
||||||
use layout_traits::{LayoutControlChan, LayoutTaskFactory};
|
use layout_traits::{LayoutControlChan, LayoutTaskFactory};
|
||||||
use msg::compositor_msg::Epoch;
|
use msg::compositor_msg::Epoch;
|
||||||
use msg::constellation_msg::AnimationState;
|
use msg::constellation_msg::AnimationState;
|
||||||
|
@ -37,19 +40,21 @@ use net_traits::image_cache_task::ImageCacheTask;
|
||||||
use net_traits::storage_task::{StorageTask, StorageTaskMsg};
|
use net_traits::storage_task::{StorageTask, StorageTaskMsg};
|
||||||
use net_traits::{self, ResourceTask};
|
use net_traits::{self, ResourceTask};
|
||||||
use offscreen_gl_context::GLContextAttributes;
|
use offscreen_gl_context::GLContextAttributes;
|
||||||
use pipeline::{CompositionPipeline, InitialPipelineState, Pipeline};
|
use pipeline::{CompositionPipeline, InitialPipelineState, Pipeline, UnprivilegedPipelineContent};
|
||||||
use profile_traits::mem;
|
use profile_traits::mem;
|
||||||
use profile_traits::time;
|
use profile_traits::time;
|
||||||
|
use sandboxing;
|
||||||
use script_traits::{CompositorEvent, ConstellationControlMsg, LayoutControlMsg};
|
use script_traits::{CompositorEvent, ConstellationControlMsg, LayoutControlMsg};
|
||||||
use script_traits::{ScriptState, ScriptTaskFactory};
|
use script_traits::{ScriptState, ScriptTaskFactory};
|
||||||
use script_traits::{TimerEventRequest};
|
use script_traits::{TimerEventRequest};
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::env;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem::replace;
|
use std::mem::replace;
|
||||||
use std::process;
|
use std::process;
|
||||||
use std::sync::mpsc::{Receiver, Sender, channel};
|
use std::sync::mpsc::{Sender, channel, Receiver};
|
||||||
use style_traits::viewport::ViewportConstraints;
|
use style_traits::viewport::ViewportConstraints;
|
||||||
use timer_scheduler::TimerScheduler;
|
use timer_scheduler::TimerScheduler;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -79,7 +84,7 @@ pub struct Constellation<LTF, STF> {
|
||||||
pub script_sender: ConstellationChan<FromScriptMsg>,
|
pub script_sender: ConstellationChan<FromScriptMsg>,
|
||||||
|
|
||||||
/// A channel through which compositor messages can be sent to this object.
|
/// A channel through which compositor messages can be sent to this object.
|
||||||
pub compositor_sender: ConstellationChan<FromCompositorMsg>,
|
pub compositor_sender: Sender<FromCompositorMsg>,
|
||||||
|
|
||||||
/// Receives messages from scripts.
|
/// Receives messages from scripts.
|
||||||
pub script_receiver: Receiver<FromScriptMsg>,
|
pub script_receiver: Receiver<FromScriptMsg>,
|
||||||
|
@ -156,6 +161,9 @@ pub struct Constellation<LTF, STF> {
|
||||||
webgl_paint_tasks: Vec<Sender<CanvasMsg>>,
|
webgl_paint_tasks: Vec<Sender<CanvasMsg>>,
|
||||||
|
|
||||||
scheduler_chan: IpcSender<TimerEventRequest>,
|
scheduler_chan: IpcSender<TimerEventRequest>,
|
||||||
|
|
||||||
|
/// A list of child content processes.
|
||||||
|
child_processes: Vec<ChildProcess>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// State needed to construct a constellation.
|
/// State needed to construct a constellation.
|
||||||
|
@ -259,14 +267,21 @@ enum ExitPipelineMode {
|
||||||
Force,
|
Force,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ChildProcess {
|
||||||
|
Sandboxed(gaol::platform::process::Process),
|
||||||
|
Unsandboxed(process::Child),
|
||||||
|
}
|
||||||
|
|
||||||
impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||||
pub fn start(state: InitialConstellationState) -> ConstellationChan<FromCompositorMsg> {
|
pub fn start(state: InitialConstellationState) -> Sender<FromCompositorMsg> {
|
||||||
let (script_receiver, script_sender) = ConstellationChan::<FromScriptMsg>::new();
|
let (ipc_script_receiver, ipc_script_sender) = ConstellationChan::<FromScriptMsg>::new();
|
||||||
let (compositor_receiver, compositor_sender) = ConstellationChan::<FromCompositorMsg>::new();
|
//let (script_receiver, script_sender) = channel();
|
||||||
|
let script_receiver = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_script_receiver);
|
||||||
|
let (compositor_sender, compositor_receiver) = channel();
|
||||||
let compositor_sender_clone = compositor_sender.clone();
|
let compositor_sender_clone = compositor_sender.clone();
|
||||||
spawn_named("Constellation".to_owned(), move || {
|
spawn_named("Constellation".to_owned(), move || {
|
||||||
let mut constellation: Constellation<LTF, STF> = Constellation {
|
let mut constellation: Constellation<LTF, STF> = Constellation {
|
||||||
script_sender: script_sender,
|
script_sender: ipc_script_sender,
|
||||||
compositor_sender: compositor_sender_clone,
|
compositor_sender: compositor_sender_clone,
|
||||||
script_receiver: script_receiver,
|
script_receiver: script_receiver,
|
||||||
compositor_receiver: compositor_receiver,
|
compositor_receiver: compositor_receiver,
|
||||||
|
@ -305,6 +320,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||||
canvas_paint_tasks: Vec::new(),
|
canvas_paint_tasks: Vec::new(),
|
||||||
webgl_paint_tasks: Vec::new(),
|
webgl_paint_tasks: Vec::new(),
|
||||||
scheduler_chan: TimerScheduler::start(),
|
scheduler_chan: TimerScheduler::start(),
|
||||||
|
child_processes: Vec::new(),
|
||||||
};
|
};
|
||||||
let namespace_id = constellation.next_pipeline_namespace_id();
|
let namespace_id = constellation.next_pipeline_namespace_id();
|
||||||
PipelineNamespace::install(namespace_id);
|
PipelineNamespace::install(namespace_id);
|
||||||
|
@ -333,10 +349,10 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||||
pipeline_id: PipelineId,
|
pipeline_id: PipelineId,
|
||||||
parent_info: Option<(PipelineId, SubpageId)>,
|
parent_info: Option<(PipelineId, SubpageId)>,
|
||||||
initial_window_size: Option<TypedSize2D<PagePx, f32>>,
|
initial_window_size: Option<TypedSize2D<PagePx, f32>>,
|
||||||
script_channel: Option<Sender<ConstellationControlMsg>>,
|
script_channel: Option<IpcSender<ConstellationControlMsg>>,
|
||||||
load_data: LoadData) {
|
load_data: LoadData) {
|
||||||
let spawning_paint_only = script_channel.is_some();
|
let spawning_paint_only = script_channel.is_some();
|
||||||
let (pipeline, mut pipeline_content) =
|
let (pipeline, unprivileged_pipeline_content, mut privileged_pipeline_content) =
|
||||||
Pipeline::create::<LTF, STF>(InitialPipelineState {
|
Pipeline::create::<LTF, STF>(InitialPipelineState {
|
||||||
id: pipeline_id,
|
id: pipeline_id,
|
||||||
parent_info: parent_info,
|
parent_info: parent_info,
|
||||||
|
@ -357,12 +373,39 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||||
pipeline_namespace_id: self.next_pipeline_namespace_id(),
|
pipeline_namespace_id: self.next_pipeline_namespace_id(),
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO(pcwalton): In multiprocess mode, send that `PipelineContent` instance over to
|
|
||||||
// the content process and call this over there.
|
|
||||||
if spawning_paint_only {
|
if spawning_paint_only {
|
||||||
pipeline_content.start_paint_task();
|
privileged_pipeline_content.start_paint_task();
|
||||||
} else {
|
} else {
|
||||||
pipeline_content.start_all::<LTF, STF>();
|
privileged_pipeline_content.start_all();
|
||||||
|
|
||||||
|
// Spawn the child process.
|
||||||
|
//
|
||||||
|
// Yes, that's all there is to it!
|
||||||
|
if opts::multiprocess() {
|
||||||
|
let (server, token) =
|
||||||
|
IpcOneShotServer::<IpcSender<UnprivilegedPipelineContent>>::new().unwrap();
|
||||||
|
|
||||||
|
// 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().unwrap();
|
||||||
|
command.arg("--content-process").arg(token);
|
||||||
|
let profile = sandboxing::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().unwrap();
|
||||||
|
let mut child_process = process::Command::new(path_to_self);
|
||||||
|
child_process.arg("--content-process");
|
||||||
|
child_process.arg(token);
|
||||||
|
ChildProcess::Unsandboxed(child_process.spawn().unwrap())
|
||||||
|
};
|
||||||
|
self.child_processes.push(child_process);
|
||||||
|
|
||||||
|
let (_receiver, sender) = server.accept().unwrap();
|
||||||
|
sender.send(unprivileged_pipeline_content).unwrap();
|
||||||
|
} else {
|
||||||
|
unprivileged_pipeline_content.start_all::<LTF, STF>(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert!(!self.pipelines.contains_key(&pipeline_id));
|
assert!(!self.pipelines.contains_key(&pipeline_id));
|
||||||
|
@ -1290,7 +1333,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||||
|
|
||||||
// Synchronously query the script task for this pipeline
|
// Synchronously query the script task for this pipeline
|
||||||
// to see if it is idle.
|
// to see if it is idle.
|
||||||
let (sender, receiver) = channel();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
let msg = ConstellationControlMsg::GetCurrentState(sender, frame.current);
|
let msg = ConstellationControlMsg::GetCurrentState(sender, frame.current);
|
||||||
pipeline.script_chan.send(msg).unwrap();
|
pipeline.script_chan.send(msg).unwrap();
|
||||||
let result = receiver.recv().unwrap();
|
let result = receiver.recv().unwrap();
|
||||||
|
@ -1445,7 +1488,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||||
if let Some(root_frame_id) = self.root_frame_id {
|
if let Some(root_frame_id) = self.root_frame_id {
|
||||||
let frame_tree = self.frame_to_sendable(root_frame_id);
|
let frame_tree = self.frame_to_sendable(root_frame_id);
|
||||||
|
|
||||||
let (chan, port) = channel();
|
let (chan, port) = ipc::channel().unwrap();
|
||||||
self.compositor_proxy.send(ToCompositorMsg::SetFrameTree(frame_tree,
|
self.compositor_proxy.send(ToCompositorMsg::SetFrameTree(frame_tree,
|
||||||
chan,
|
chan,
|
||||||
self.compositor_sender.clone()));
|
self.compositor_sender.clone()));
|
||||||
|
|
|
@ -8,9 +8,10 @@ use euclid::scale_factor::ScaleFactor;
|
||||||
use euclid::{Point2D, Size2D};
|
use euclid::{Point2D, Size2D};
|
||||||
use msg::constellation_msg::AnimationState;
|
use msg::constellation_msg::AnimationState;
|
||||||
use msg::constellation_msg::CompositorMsg as ConstellationMsg;
|
use msg::constellation_msg::CompositorMsg as ConstellationMsg;
|
||||||
use msg::constellation_msg::{ConstellationChan, WindowSizeData};
|
use msg::constellation_msg::WindowSizeData;
|
||||||
use profile_traits::mem;
|
use profile_traits::mem;
|
||||||
use profile_traits::time;
|
use profile_traits::time;
|
||||||
|
use std::sync::mpsc::Sender;
|
||||||
use util::opts;
|
use util::opts;
|
||||||
use windowing::WindowEvent;
|
use windowing::WindowEvent;
|
||||||
|
|
||||||
|
@ -22,7 +23,7 @@ pub struct NullCompositor {
|
||||||
/// The port on which we receive messages.
|
/// The port on which we receive messages.
|
||||||
pub port: Box<CompositorReceiver>,
|
pub port: Box<CompositorReceiver>,
|
||||||
/// A channel to the constellation.
|
/// A channel to the constellation.
|
||||||
constellation_chan: ConstellationChan<ConstellationMsg>,
|
constellation_chan: Sender<ConstellationMsg>,
|
||||||
/// A channel to the time profiler.
|
/// A channel to the time profiler.
|
||||||
time_profiler_chan: time::ProfilerChan,
|
time_profiler_chan: time::ProfilerChan,
|
||||||
/// A channel to the memory profiler.
|
/// A channel to the memory profiler.
|
||||||
|
@ -44,8 +45,7 @@ impl NullCompositor {
|
||||||
|
|
||||||
// Tell the constellation about the initial fake size.
|
// Tell the constellation about the initial fake size.
|
||||||
{
|
{
|
||||||
let ConstellationChan(ref chan) = compositor.constellation_chan;
|
compositor.constellation_chan.send(ConstellationMsg::ResizedWindow(WindowSizeData {
|
||||||
chan.send(ConstellationMsg::ResizedWindow(WindowSizeData {
|
|
||||||
initial_viewport: Size2D::typed(800_f32, 600_f32),
|
initial_viewport: Size2D::typed(800_f32, 600_f32),
|
||||||
visible_viewport: Size2D::typed(800_f32, 600_f32),
|
visible_viewport: Size2D::typed(800_f32, 600_f32),
|
||||||
device_pixel_ratio:
|
device_pixel_ratio:
|
||||||
|
@ -62,8 +62,7 @@ impl CompositorEventListener for NullCompositor {
|
||||||
match self.port.recv_compositor_msg() {
|
match self.port.recv_compositor_msg() {
|
||||||
Msg::Exit(chan) => {
|
Msg::Exit(chan) => {
|
||||||
debug!("shutting down the constellation");
|
debug!("shutting down the constellation");
|
||||||
let ConstellationChan(ref con_chan) = self.constellation_chan;
|
self.constellation_chan.send(ConstellationMsg::Exit).unwrap();
|
||||||
con_chan.send(ConstellationMsg::Exit).unwrap();
|
|
||||||
chan.send(()).unwrap();
|
chan.send(()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +99,7 @@ impl CompositorEventListener for NullCompositor {
|
||||||
AnimationState::NoAnimationCallbacksPresent => {}
|
AnimationState::NoAnimationCallbacksPresent => {}
|
||||||
AnimationState::AnimationCallbacksPresent => {
|
AnimationState::AnimationCallbacksPresent => {
|
||||||
let msg = ConstellationMsg::TickAnimation(pipeline_id);
|
let msg = ConstellationMsg::TickAnimation(pipeline_id);
|
||||||
self.constellation_chan.0.send(msg).unwrap()
|
self.constellation_chan.send(msg).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
|
#![feature(custom_derive)]
|
||||||
#![feature(iter_cmp)]
|
#![feature(iter_cmp)]
|
||||||
|
#![feature(plugin)]
|
||||||
#![feature(slice_bytes)]
|
#![feature(slice_bytes)]
|
||||||
#![feature(vec_push_all)]
|
#![feature(vec_push_all)]
|
||||||
#![feature(mpsc_select)]
|
#![feature(mpsc_select)]
|
||||||
|
@ -11,6 +13,7 @@
|
||||||
#![plugin(plugins)]
|
#![plugin(plugins)]
|
||||||
|
|
||||||
#![deny(unsafe_code)]
|
#![deny(unsafe_code)]
|
||||||
|
#![plugin(serde_macros)]
|
||||||
|
|
||||||
extern crate app_units;
|
extern crate app_units;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -31,6 +34,7 @@ extern crate core_text;
|
||||||
|
|
||||||
extern crate devtools_traits;
|
extern crate devtools_traits;
|
||||||
extern crate euclid;
|
extern crate euclid;
|
||||||
|
extern crate gaol;
|
||||||
extern crate gfx;
|
extern crate gfx;
|
||||||
extern crate gfx_traits;
|
extern crate gfx_traits;
|
||||||
extern crate gleam;
|
extern crate gleam;
|
||||||
|
@ -43,7 +47,10 @@ extern crate net_traits;
|
||||||
extern crate num;
|
extern crate num;
|
||||||
extern crate offscreen_gl_context;
|
extern crate offscreen_gl_context;
|
||||||
extern crate script_traits;
|
extern crate script_traits;
|
||||||
|
extern crate serde;
|
||||||
extern crate style_traits;
|
extern crate style_traits;
|
||||||
|
|
||||||
|
extern crate libc;
|
||||||
extern crate time;
|
extern crate time;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
|
|
||||||
|
@ -59,4 +66,5 @@ mod timer_scheduler;
|
||||||
pub mod compositor_task;
|
pub mod compositor_task;
|
||||||
pub mod constellation;
|
pub mod constellation;
|
||||||
pub mod pipeline;
|
pub mod pipeline;
|
||||||
|
pub mod sandboxing;
|
||||||
pub mod windowing;
|
pub mod windowing;
|
||||||
|
|
|
@ -14,6 +14,7 @@ use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
use layers::geometry::DevicePixel;
|
use layers::geometry::DevicePixel;
|
||||||
use layout_traits::{LayoutControlChan, LayoutTaskFactory};
|
use layout_traits::{LayoutControlChan, LayoutTaskFactory};
|
||||||
|
use msg::compositor_msg::ScriptToCompositorMsg;
|
||||||
use msg::constellation_msg::ScriptMsg as ConstellationMsg;
|
use msg::constellation_msg::ScriptMsg as ConstellationMsg;
|
||||||
use msg::constellation_msg::{ConstellationChan, Failure, FrameId, PipelineId, SubpageId};
|
use msg::constellation_msg::{ConstellationChan, Failure, FrameId, PipelineId, SubpageId};
|
||||||
use msg::constellation_msg::{LoadData, MozBrowserEvent, WindowSizeData};
|
use msg::constellation_msg::{LoadData, MozBrowserEvent, WindowSizeData};
|
||||||
|
@ -26,7 +27,6 @@ use profile_traits::time;
|
||||||
use script_traits::{ConstellationControlMsg, InitialScriptState};
|
use script_traits::{ConstellationControlMsg, InitialScriptState};
|
||||||
use script_traits::{LayoutControlMsg, NewLayoutInfo, ScriptTaskFactory};
|
use script_traits::{LayoutControlMsg, NewLayoutInfo, ScriptTaskFactory};
|
||||||
use script_traits::{TimerEventRequest};
|
use script_traits::{TimerEventRequest};
|
||||||
use std::any::Any;
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::sync::mpsc::{Receiver, Sender, channel};
|
use std::sync::mpsc::{Receiver, Sender, channel};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
@ -34,20 +34,21 @@ use url::Url;
|
||||||
use util;
|
use util;
|
||||||
use util::geometry::{PagePx, ViewportPx};
|
use util::geometry::{PagePx, ViewportPx};
|
||||||
use util::ipc::OptionalIpcSender;
|
use util::ipc::OptionalIpcSender;
|
||||||
|
use util::opts::{self, Opts};
|
||||||
use util::prefs;
|
use util::prefs;
|
||||||
|
|
||||||
/// A uniquely-identifiable pipeline of script task, layout task, and paint task.
|
/// A uniquely-identifiable pipeline of script task, layout task, and paint task.
|
||||||
pub struct Pipeline {
|
pub struct Pipeline {
|
||||||
pub id: PipelineId,
|
pub id: PipelineId,
|
||||||
pub parent_info: Option<(PipelineId, SubpageId)>,
|
pub parent_info: Option<(PipelineId, SubpageId)>,
|
||||||
pub script_chan: Sender<ConstellationControlMsg>,
|
pub script_chan: IpcSender<ConstellationControlMsg>,
|
||||||
/// A channel to layout, for performing reflows and shutdown.
|
/// A channel to layout, for performing reflows and shutdown.
|
||||||
pub layout_chan: LayoutControlChan,
|
pub layout_chan: LayoutControlChan,
|
||||||
/// A channel to the compositor.
|
/// A channel to the compositor.
|
||||||
pub compositor_proxy: Box<CompositorProxy + 'static + Send>,
|
pub compositor_proxy: Box<CompositorProxy + 'static + Send>,
|
||||||
pub chrome_to_paint_chan: Sender<ChromeToPaintMsg>,
|
pub chrome_to_paint_chan: Sender<ChromeToPaintMsg>,
|
||||||
pub layout_shutdown_port: Receiver<()>,
|
pub layout_shutdown_port: IpcReceiver<()>,
|
||||||
pub paint_shutdown_port: Receiver<()>,
|
pub paint_shutdown_port: IpcReceiver<()>,
|
||||||
/// URL corresponding to the most recently-loaded page.
|
/// URL corresponding to the most recently-loaded page.
|
||||||
pub url: Url,
|
pub url: Url,
|
||||||
/// The title of the most recently-loaded page.
|
/// The title of the most recently-loaded page.
|
||||||
|
@ -63,7 +64,7 @@ pub struct Pipeline {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CompositionPipeline {
|
pub struct CompositionPipeline {
|
||||||
pub id: PipelineId,
|
pub id: PipelineId,
|
||||||
pub script_chan: Sender<ConstellationControlMsg>,
|
pub script_chan: IpcSender<ConstellationControlMsg>,
|
||||||
pub layout_chan: LayoutControlChan,
|
pub layout_chan: LayoutControlChan,
|
||||||
pub chrome_to_paint_chan: Sender<ChromeToPaintMsg>,
|
pub chrome_to_paint_chan: Sender<ChromeToPaintMsg>,
|
||||||
}
|
}
|
||||||
|
@ -104,7 +105,7 @@ pub struct InitialPipelineState {
|
||||||
pub device_pixel_ratio: ScaleFactor<ViewportPx, DevicePixel, f32>,
|
pub device_pixel_ratio: ScaleFactor<ViewportPx, DevicePixel, f32>,
|
||||||
/// A channel to the script thread, if applicable. If this is `Some`,
|
/// A channel to the script thread, if applicable. If this is `Some`,
|
||||||
/// then `parent_info` must also be `Some`.
|
/// then `parent_info` must also be `Some`.
|
||||||
pub script_chan: Option<Sender<ConstellationControlMsg>>,
|
pub script_chan: Option<IpcSender<ConstellationControlMsg>>,
|
||||||
/// Information about the page to load.
|
/// Information about the page to load.
|
||||||
pub load_data: LoadData,
|
pub load_data: LoadData,
|
||||||
/// The ID of the pipeline namespace for this script thread.
|
/// The ID of the pipeline namespace for this script thread.
|
||||||
|
@ -115,13 +116,14 @@ impl Pipeline {
|
||||||
/// Starts a paint task, layout task, and possibly a script task.
|
/// Starts a paint task, layout task, and possibly a script task.
|
||||||
/// Returns the channels wrapped in a struct.
|
/// Returns the channels wrapped in a struct.
|
||||||
pub fn create<LTF, STF>(state: InitialPipelineState)
|
pub fn create<LTF, STF>(state: InitialPipelineState)
|
||||||
-> (Pipeline, PipelineContent)
|
-> (Pipeline, UnprivilegedPipelineContent, PrivilegedPipelineContent)
|
||||||
where LTF: LayoutTaskFactory, STF: ScriptTaskFactory {
|
where LTF: LayoutTaskFactory, STF: ScriptTaskFactory {
|
||||||
let (layout_to_paint_chan, layout_to_paint_port) = util::ipc::optional_ipc_channel();
|
let (layout_to_paint_chan, layout_to_paint_port) = util::ipc::optional_ipc_channel();
|
||||||
let (chrome_to_paint_chan, chrome_to_paint_port) = channel();
|
let (chrome_to_paint_chan, chrome_to_paint_port) = channel();
|
||||||
let (paint_shutdown_chan, paint_shutdown_port) = channel();
|
let (paint_shutdown_chan, paint_shutdown_port) = ipc::channel().unwrap();
|
||||||
let (layout_shutdown_chan, layout_shutdown_port) = channel();
|
let (layout_shutdown_chan, layout_shutdown_port) = ipc::channel().unwrap();
|
||||||
let (pipeline_chan, pipeline_port) = ipc::channel().unwrap();
|
let (pipeline_chan, pipeline_port) = ipc::channel().unwrap();
|
||||||
|
let (script_to_compositor_chan, script_to_compositor_port) = ipc::channel().unwrap();
|
||||||
let mut pipeline_port = Some(pipeline_port);
|
let mut pipeline_port = Some(pipeline_port);
|
||||||
|
|
||||||
let failure = Failure {
|
let failure = Failure {
|
||||||
|
@ -148,6 +150,9 @@ impl Pipeline {
|
||||||
script_to_devtools_chan
|
script_to_devtools_chan
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let (layout_content_process_shutdown_chan, layout_content_process_shutdown_port) =
|
||||||
|
ipc::channel().unwrap();
|
||||||
|
|
||||||
let (script_chan, script_port) = match state.script_chan {
|
let (script_chan, script_port) = match state.script_chan {
|
||||||
Some(script_chan) => {
|
Some(script_chan) => {
|
||||||
let (containing_pipeline_id, subpage_id) =
|
let (containing_pipeline_id, subpage_id) =
|
||||||
|
@ -157,10 +162,11 @@ impl Pipeline {
|
||||||
new_pipeline_id: state.id,
|
new_pipeline_id: state.id,
|
||||||
subpage_id: subpage_id,
|
subpage_id: subpage_id,
|
||||||
load_data: state.load_data.clone(),
|
load_data: state.load_data.clone(),
|
||||||
paint_chan: box layout_to_paint_chan.clone() as Box<Any + Send>,
|
paint_chan: layout_to_paint_chan.clone().to_opaque(),
|
||||||
failure: failure,
|
failure: failure,
|
||||||
pipeline_port: mem::replace(&mut pipeline_port, None).unwrap(),
|
pipeline_port: mem::replace(&mut pipeline_port, None).unwrap(),
|
||||||
layout_shutdown_chan: layout_shutdown_chan.clone(),
|
layout_shutdown_chan: layout_shutdown_chan.clone(),
|
||||||
|
content_process_shutdown_chan: layout_content_process_shutdown_chan.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
script_chan.send(ConstellationControlMsg::AttachLayout(new_layout_info))
|
script_chan.send(ConstellationControlMsg::AttachLayout(new_layout_info))
|
||||||
|
@ -168,11 +174,14 @@ impl Pipeline {
|
||||||
(script_chan, None)
|
(script_chan, None)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let (script_chan, script_port) = channel();
|
let (script_chan, script_port) = ipc::channel().unwrap();
|
||||||
(script_chan, Some(script_port))
|
(script_chan, Some(script_port))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let (script_content_process_shutdown_chan, script_content_process_shutdown_port) =
|
||||||
|
ipc::channel().unwrap();
|
||||||
|
|
||||||
let pipeline = Pipeline::new(state.id,
|
let pipeline = Pipeline::new(state.id,
|
||||||
state.parent_info,
|
state.parent_info,
|
||||||
script_chan.clone(),
|
script_chan.clone(),
|
||||||
|
@ -184,45 +193,63 @@ impl Pipeline {
|
||||||
state.load_data.url.clone(),
|
state.load_data.url.clone(),
|
||||||
state.window_size);
|
state.window_size);
|
||||||
|
|
||||||
let pipeline_content = PipelineContent {
|
let unprivileged_pipeline_content = UnprivilegedPipelineContent {
|
||||||
id: state.id,
|
id: state.id,
|
||||||
parent_info: state.parent_info,
|
parent_info: state.parent_info,
|
||||||
constellation_chan: state.constellation_chan,
|
constellation_chan: state.constellation_chan.clone(),
|
||||||
scheduler_chan: state.scheduler_chan,
|
scheduler_chan: state.scheduler_chan,
|
||||||
compositor_proxy: state.compositor_proxy,
|
|
||||||
devtools_chan: script_to_devtools_chan,
|
devtools_chan: script_to_devtools_chan,
|
||||||
image_cache_task: state.image_cache_task,
|
image_cache_task: state.image_cache_task,
|
||||||
font_cache_task: state.font_cache_task,
|
font_cache_task: state.font_cache_task.clone(),
|
||||||
resource_task: state.resource_task,
|
resource_task: state.resource_task,
|
||||||
storage_task: state.storage_task,
|
storage_task: state.storage_task,
|
||||||
time_profiler_chan: state.time_profiler_chan,
|
time_profiler_chan: state.time_profiler_chan.clone(),
|
||||||
mem_profiler_chan: state.mem_profiler_chan,
|
mem_profiler_chan: state.mem_profiler_chan.clone(),
|
||||||
window_size: window_size,
|
window_size: window_size,
|
||||||
script_chan: script_chan,
|
script_chan: script_chan,
|
||||||
load_data: state.load_data,
|
load_data: state.load_data.clone(),
|
||||||
failure: failure,
|
failure: failure,
|
||||||
script_port: script_port,
|
script_port: script_port,
|
||||||
|
opts: (*opts::get()).clone(),
|
||||||
layout_to_paint_chan: layout_to_paint_chan,
|
layout_to_paint_chan: layout_to_paint_chan,
|
||||||
chrome_to_paint_chan: chrome_to_paint_chan,
|
|
||||||
layout_to_paint_port: Some(layout_to_paint_port),
|
|
||||||
chrome_to_paint_port: Some(chrome_to_paint_port),
|
|
||||||
pipeline_port: pipeline_port,
|
pipeline_port: pipeline_port,
|
||||||
paint_shutdown_chan: paint_shutdown_chan,
|
|
||||||
layout_shutdown_chan: layout_shutdown_chan,
|
layout_shutdown_chan: layout_shutdown_chan,
|
||||||
|
paint_shutdown_chan: paint_shutdown_chan.clone(),
|
||||||
|
script_to_compositor_chan: script_to_compositor_chan,
|
||||||
pipeline_namespace_id: state.pipeline_namespace_id,
|
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,
|
||||||
};
|
};
|
||||||
|
|
||||||
(pipeline, pipeline_content)
|
let privileged_pipeline_content = PrivilegedPipelineContent {
|
||||||
|
id: state.id,
|
||||||
|
constellation_chan: state.constellation_chan,
|
||||||
|
compositor_proxy: state.compositor_proxy,
|
||||||
|
font_cache_task: state.font_cache_task,
|
||||||
|
time_profiler_chan: state.time_profiler_chan,
|
||||||
|
mem_profiler_chan: state.mem_profiler_chan,
|
||||||
|
load_data: state.load_data,
|
||||||
|
failure: failure,
|
||||||
|
layout_to_paint_port: Some(layout_to_paint_port),
|
||||||
|
chrome_to_paint_chan: chrome_to_paint_chan,
|
||||||
|
chrome_to_paint_port: Some(chrome_to_paint_port),
|
||||||
|
paint_shutdown_chan: paint_shutdown_chan,
|
||||||
|
script_to_compositor_port: Some(script_to_compositor_port),
|
||||||
|
};
|
||||||
|
|
||||||
|
(pipeline, unprivileged_pipeline_content, privileged_pipeline_content)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(id: PipelineId,
|
pub fn new(id: PipelineId,
|
||||||
parent_info: Option<(PipelineId, SubpageId)>,
|
parent_info: Option<(PipelineId, SubpageId)>,
|
||||||
script_chan: Sender<ConstellationControlMsg>,
|
script_chan: IpcSender<ConstellationControlMsg>,
|
||||||
layout_chan: LayoutControlChan,
|
layout_chan: LayoutControlChan,
|
||||||
compositor_proxy: Box<CompositorProxy + 'static + Send>,
|
compositor_proxy: Box<CompositorProxy + 'static + Send>,
|
||||||
chrome_to_paint_chan: Sender<ChromeToPaintMsg>,
|
chrome_to_paint_chan: Sender<ChromeToPaintMsg>,
|
||||||
layout_shutdown_port: Receiver<()>,
|
layout_shutdown_port: IpcReceiver<()>,
|
||||||
paint_shutdown_port: Receiver<()>,
|
paint_shutdown_port: IpcReceiver<()>,
|
||||||
url: Url,
|
url: Url,
|
||||||
size: Option<TypedSize2D<PagePx, f32>>)
|
size: Option<TypedSize2D<PagePx, f32>>)
|
||||||
-> Pipeline {
|
-> Pipeline {
|
||||||
|
@ -315,13 +342,14 @@ impl Pipeline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PipelineContent {
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct UnprivilegedPipelineContent {
|
||||||
id: PipelineId,
|
id: PipelineId,
|
||||||
parent_info: Option<(PipelineId, SubpageId)>,
|
parent_info: Option<(PipelineId, SubpageId)>,
|
||||||
constellation_chan: ConstellationChan<ConstellationMsg>,
|
constellation_chan: ConstellationChan<ConstellationMsg>,
|
||||||
scheduler_chan: IpcSender<TimerEventRequest>,
|
scheduler_chan: IpcSender<TimerEventRequest>,
|
||||||
compositor_proxy: Box<CompositorProxy + Send + 'static>,
|
|
||||||
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
|
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
|
||||||
|
script_to_compositor_chan: IpcSender<ScriptToCompositorMsg>,
|
||||||
image_cache_task: ImageCacheTask,
|
image_cache_task: ImageCacheTask,
|
||||||
font_cache_task: FontCacheTask,
|
font_cache_task: FontCacheTask,
|
||||||
resource_task: ResourceTask,
|
resource_task: ResourceTask,
|
||||||
|
@ -329,39 +357,31 @@ pub struct PipelineContent {
|
||||||
time_profiler_chan: time::ProfilerChan,
|
time_profiler_chan: time::ProfilerChan,
|
||||||
mem_profiler_chan: profile_mem::ProfilerChan,
|
mem_profiler_chan: profile_mem::ProfilerChan,
|
||||||
window_size: Option<WindowSizeData>,
|
window_size: Option<WindowSizeData>,
|
||||||
script_chan: Sender<ConstellationControlMsg>,
|
script_chan: IpcSender<ConstellationControlMsg>,
|
||||||
load_data: LoadData,
|
load_data: LoadData,
|
||||||
failure: Failure,
|
failure: Failure,
|
||||||
script_port: Option<Receiver<ConstellationControlMsg>>,
|
script_port: Option<IpcReceiver<ConstellationControlMsg>>,
|
||||||
layout_to_paint_chan: OptionalIpcSender<LayoutToPaintMsg>,
|
layout_to_paint_chan: OptionalIpcSender<LayoutToPaintMsg>,
|
||||||
chrome_to_paint_chan: Sender<ChromeToPaintMsg>,
|
opts: Opts,
|
||||||
layout_to_paint_port: Option<Receiver<LayoutToPaintMsg>>,
|
paint_shutdown_chan: IpcSender<()>,
|
||||||
chrome_to_paint_port: Option<Receiver<ChromeToPaintMsg>>,
|
|
||||||
paint_shutdown_chan: Sender<()>,
|
|
||||||
pipeline_port: Option<IpcReceiver<LayoutControlMsg>>,
|
pipeline_port: Option<IpcReceiver<LayoutControlMsg>>,
|
||||||
layout_shutdown_chan: Sender<()>,
|
|
||||||
pipeline_namespace_id: PipelineNamespaceId,
|
pipeline_namespace_id: PipelineNamespaceId,
|
||||||
|
layout_shutdown_chan: IpcSender<()>,
|
||||||
|
layout_content_process_shutdown_chan: IpcSender<()>,
|
||||||
|
layout_content_process_shutdown_port: IpcReceiver<()>,
|
||||||
|
script_content_process_shutdown_chan: IpcSender<()>,
|
||||||
|
script_content_process_shutdown_port: IpcReceiver<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PipelineContent {
|
impl UnprivilegedPipelineContent {
|
||||||
pub fn start_all<LTF, STF>(mut self) where LTF: LayoutTaskFactory, STF: ScriptTaskFactory {
|
pub fn start_all<LTF, STF>(mut self, wait_for_completion: bool)
|
||||||
|
where LTF: LayoutTaskFactory, STF: ScriptTaskFactory {
|
||||||
let layout_pair = ScriptTaskFactory::create_layout_channel(None::<&mut STF>);
|
let layout_pair = ScriptTaskFactory::create_layout_channel(None::<&mut STF>);
|
||||||
let (script_to_compositor_chan, script_to_compositor_port) = ipc::channel().unwrap();
|
|
||||||
|
|
||||||
self.start_paint_task();
|
|
||||||
|
|
||||||
let compositor_proxy_for_script_listener_thread =
|
|
||||||
self.compositor_proxy.clone_compositor_proxy();
|
|
||||||
thread::spawn(move || {
|
|
||||||
compositor_task::run_script_listener_thread(
|
|
||||||
compositor_proxy_for_script_listener_thread,
|
|
||||||
script_to_compositor_port)
|
|
||||||
});
|
|
||||||
|
|
||||||
ScriptTaskFactory::create(None::<&mut STF>, InitialScriptState {
|
ScriptTaskFactory::create(None::<&mut STF>, InitialScriptState {
|
||||||
id: self.id,
|
id: self.id,
|
||||||
parent_info: self.parent_info,
|
parent_info: self.parent_info,
|
||||||
compositor: script_to_compositor_chan,
|
compositor: self.script_to_compositor_chan.clone(),
|
||||||
control_chan: self.script_chan.clone(),
|
control_chan: self.script_chan.clone(),
|
||||||
control_port: mem::replace(&mut self.script_port, None).unwrap(),
|
control_port: mem::replace(&mut self.script_port, None).unwrap(),
|
||||||
constellation_chan: self.constellation_chan.clone(),
|
constellation_chan: self.constellation_chan.clone(),
|
||||||
|
@ -375,6 +395,7 @@ impl PipelineContent {
|
||||||
devtools_chan: self.devtools_chan,
|
devtools_chan: self.devtools_chan,
|
||||||
window_size: self.window_size,
|
window_size: self.window_size,
|
||||||
pipeline_namespace_id: self.pipeline_namespace_id,
|
pipeline_namespace_id: self.pipeline_namespace_id,
|
||||||
|
content_process_shutdown_chan: self.script_content_process_shutdown_chan.clone(),
|
||||||
}, &layout_pair, self.load_data.clone());
|
}, &layout_pair, self.load_data.clone());
|
||||||
|
|
||||||
LayoutTaskFactory::create(None::<&mut LTF>,
|
LayoutTaskFactory::create(None::<&mut LTF>,
|
||||||
|
@ -391,7 +412,49 @@ impl PipelineContent {
|
||||||
self.font_cache_task,
|
self.font_cache_task,
|
||||||
self.time_profiler_chan,
|
self.time_profiler_chan,
|
||||||
self.mem_profiler_chan,
|
self.mem_profiler_chan,
|
||||||
self.layout_shutdown_chan);
|
self.layout_shutdown_chan,
|
||||||
|
self.layout_content_process_shutdown_chan.clone());
|
||||||
|
|
||||||
|
if wait_for_completion {
|
||||||
|
self.script_content_process_shutdown_port.recv().unwrap();
|
||||||
|
self.layout_content_process_shutdown_port.recv().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn opts(&self) -> Opts {
|
||||||
|
self.opts.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PrivilegedPipelineContent {
|
||||||
|
id: PipelineId,
|
||||||
|
constellation_chan: ConstellationChan<ConstellationMsg>,
|
||||||
|
compositor_proxy: Box<CompositorProxy + Send + 'static>,
|
||||||
|
script_to_compositor_port: Option<IpcReceiver<ScriptToCompositorMsg>>,
|
||||||
|
font_cache_task: FontCacheTask,
|
||||||
|
time_profiler_chan: time::ProfilerChan,
|
||||||
|
mem_profiler_chan: profile_mem::ProfilerChan,
|
||||||
|
load_data: LoadData,
|
||||||
|
failure: Failure,
|
||||||
|
layout_to_paint_port: Option<Receiver<LayoutToPaintMsg>>,
|
||||||
|
chrome_to_paint_chan: Sender<ChromeToPaintMsg>,
|
||||||
|
chrome_to_paint_port: Option<Receiver<ChromeToPaintMsg>>,
|
||||||
|
paint_shutdown_chan: IpcSender<()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PrivilegedPipelineContent {
|
||||||
|
pub fn start_all(&mut self) {
|
||||||
|
self.start_paint_task();
|
||||||
|
|
||||||
|
let compositor_proxy_for_script_listener_thread =
|
||||||
|
self.compositor_proxy.clone_compositor_proxy();
|
||||||
|
let script_to_compositor_port =
|
||||||
|
mem::replace(&mut self.script_to_compositor_port, None).unwrap();
|
||||||
|
thread::spawn(move || {
|
||||||
|
compositor_task::run_script_listener_thread(
|
||||||
|
compositor_proxy_for_script_listener_thread,
|
||||||
|
script_to_compositor_port)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_paint_task(&mut self) {
|
pub fn start_paint_task(&mut self) {
|
||||||
|
|
38
components/compositing/sandboxing.rs
Normal file
38
components/compositing/sandboxing.rs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use gaol::platform;
|
||||||
|
use gaol::profile::{Operation, PathPattern, Profile};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use util::resource_files;
|
||||||
|
|
||||||
|
/// Our content process sandbox profile on Mac. As restrictive as possible.
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
pub fn content_process_sandbox_profile() -> Profile {
|
||||||
|
Profile::new(vec![
|
||||||
|
Operation::FileReadAll(PathPattern::Literal(PathBuf::from("/dev/urandom"))),
|
||||||
|
Operation::FileReadAll(PathPattern::Subpath(resource_files::resources_dir_path())),
|
||||||
|
Operation::FileReadAll(PathPattern::Subpath(PathBuf::from("/Library/Fonts"))),
|
||||||
|
Operation::FileReadAll(PathPattern::Subpath(PathBuf::from("/System/Library/Fonts"))),
|
||||||
|
Operation::FileReadAll(PathPattern::Subpath(PathBuf::from(
|
||||||
|
"/System/Library/Frameworks/ApplicationServices.framework/"))),
|
||||||
|
Operation::FileReadMetadata(PathPattern::Literal(PathBuf::from("/"))),
|
||||||
|
Operation::FileReadMetadata(PathPattern::Literal(PathBuf::from("/Library"))),
|
||||||
|
Operation::FileReadMetadata(PathPattern::Literal(PathBuf::from("/System"))),
|
||||||
|
Operation::FileReadMetadata(PathPattern::Literal(PathBuf::from("/etc"))),
|
||||||
|
Operation::SystemInfoRead,
|
||||||
|
Operation::PlatformSpecific(platform::macos::Operation::MachLookup(
|
||||||
|
b"com.apple.FontServer".to_vec())),
|
||||||
|
]).expect("Failed to create sandbox profile!")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Our content process sandbox profile on Linux. As restrictive as possible.
|
||||||
|
#[cfg(not(target_os = "macos"))]
|
||||||
|
pub fn content_process_sandbox_profile() -> Profile {
|
||||||
|
Profile::new(vec![
|
||||||
|
Operation::FileReadAll(PathPattern::Literal(PathBuf::from("/dev/urandom"))),
|
||||||
|
Operation::FileReadAll(PathPattern::Subpath(resource_files::resources_dir_path())),
|
||||||
|
]).expect("Failed to create sandbox profile!")
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use font_template::{FontTemplate, FontTemplateDescriptor};
|
use font_template::{FontTemplate, FontTemplateDescriptor};
|
||||||
use ipc_channel::ipc;
|
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
use net_traits::{AsyncResponseTarget, PendingAsyncLoad, ResourceTask, ResponseAction};
|
use net_traits::{AsyncResponseTarget, PendingAsyncLoad, ResourceTask, ResponseAction};
|
||||||
use platform::font_context::FontContextHandle;
|
use platform::font_context::FontContextHandle;
|
||||||
|
@ -15,7 +15,7 @@ use platform::font_template::FontTemplateData;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::sync::mpsc::{Sender, Receiver, channel};
|
use std::sync::mpsc::channel;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
use style::font_face::Source;
|
use style::font_face::Source;
|
||||||
|
@ -77,15 +77,17 @@ impl FontFamily {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Commands that the FontContext sends to the font cache task.
|
/// Commands that the FontContext sends to the font cache task.
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
GetFontTemplate(String, FontTemplateDescriptor, Sender<Reply>),
|
GetFontTemplate(String, FontTemplateDescriptor, IpcSender<Reply>),
|
||||||
GetLastResortFontTemplate(FontTemplateDescriptor, Sender<Reply>),
|
GetLastResortFontTemplate(FontTemplateDescriptor, IpcSender<Reply>),
|
||||||
AddWebFont(Atom, Source, Sender<()>),
|
AddWebFont(Atom, Source, IpcSender<()>),
|
||||||
AddDownloadedWebFont(LowercaseString, Url, Vec<u8>, Sender<()>),
|
AddDownloadedWebFont(LowercaseString, Url, Vec<u8>, IpcSender<()>),
|
||||||
Exit(Sender<()>),
|
Exit(IpcSender<()>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reply messages sent from the font cache task to the FontContext caller.
|
/// Reply messages sent from the font cache task to the FontContext caller.
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
pub enum Reply {
|
pub enum Reply {
|
||||||
GetFontTemplateReply(Option<Arc<FontTemplateData>>),
|
GetFontTemplateReply(Option<Arc<FontTemplateData>>),
|
||||||
}
|
}
|
||||||
|
@ -93,8 +95,8 @@ pub enum Reply {
|
||||||
/// The font cache task itself. It maintains a list of reference counted
|
/// The font cache task itself. It maintains a list of reference counted
|
||||||
/// font templates that are currently in use.
|
/// font templates that are currently in use.
|
||||||
struct FontCache {
|
struct FontCache {
|
||||||
port: Receiver<Command>,
|
port: IpcReceiver<Command>,
|
||||||
channel_to_self: Sender<Command>,
|
channel_to_self: IpcSender<Command>,
|
||||||
generic_fonts: HashMap<LowercaseString, LowercaseString>,
|
generic_fonts: HashMap<LowercaseString, LowercaseString>,
|
||||||
local_families: HashMap<LowercaseString, FontFamily>,
|
local_families: HashMap<LowercaseString, FontFamily>,
|
||||||
web_families: HashMap<LowercaseString, FontFamily>,
|
web_families: HashMap<LowercaseString, FontFamily>,
|
||||||
|
@ -269,14 +271,14 @@ impl FontCache {
|
||||||
|
|
||||||
/// The public interface to the font cache task, used exclusively by
|
/// The public interface to the font cache task, used exclusively by
|
||||||
/// the per-thread/task FontContext structures.
|
/// the per-thread/task FontContext structures.
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
pub struct FontCacheTask {
|
pub struct FontCacheTask {
|
||||||
chan: Sender<Command>,
|
chan: IpcSender<Command>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FontCacheTask {
|
impl FontCacheTask {
|
||||||
pub fn new(resource_task: ResourceTask) -> FontCacheTask {
|
pub fn new(resource_task: ResourceTask) -> FontCacheTask {
|
||||||
let (chan, port) = channel();
|
let (chan, port) = ipc::channel().unwrap();
|
||||||
|
|
||||||
let channel_to_self = chan.clone();
|
let channel_to_self = chan.clone();
|
||||||
spawn_named("FontCacheTask".to_owned(), move || {
|
spawn_named("FontCacheTask".to_owned(), move || {
|
||||||
|
@ -310,7 +312,7 @@ impl FontCacheTask {
|
||||||
pub fn find_font_template(&self, family: String, desc: FontTemplateDescriptor)
|
pub fn find_font_template(&self, family: String, desc: FontTemplateDescriptor)
|
||||||
-> Option<Arc<FontTemplateData>> {
|
-> Option<Arc<FontTemplateData>> {
|
||||||
|
|
||||||
let (response_chan, response_port) = channel();
|
let (response_chan, response_port) = ipc::channel().unwrap();
|
||||||
self.chan.send(Command::GetFontTemplate(family, desc, response_chan)).unwrap();
|
self.chan.send(Command::GetFontTemplate(family, desc, response_chan)).unwrap();
|
||||||
|
|
||||||
let reply = response_port.recv().unwrap();
|
let reply = response_port.recv().unwrap();
|
||||||
|
@ -325,7 +327,7 @@ impl FontCacheTask {
|
||||||
pub fn last_resort_font_template(&self, desc: FontTemplateDescriptor)
|
pub fn last_resort_font_template(&self, desc: FontTemplateDescriptor)
|
||||||
-> Arc<FontTemplateData> {
|
-> Arc<FontTemplateData> {
|
||||||
|
|
||||||
let (response_chan, response_port) = channel();
|
let (response_chan, response_port) = ipc::channel().unwrap();
|
||||||
self.chan.send(Command::GetLastResortFontTemplate(desc, response_chan)).unwrap();
|
self.chan.send(Command::GetLastResortFontTemplate(desc, response_chan)).unwrap();
|
||||||
|
|
||||||
let reply = response_port.recv().unwrap();
|
let reply = response_port.recv().unwrap();
|
||||||
|
@ -337,12 +339,12 @@ impl FontCacheTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_web_font(&self, family: Atom, src: Source, sender: Sender<()>) {
|
pub fn add_web_font(&self, family: Atom, src: Source, sender: IpcSender<()>) {
|
||||||
self.chan.send(Command::AddWebFont(family, src, sender)).unwrap();
|
self.chan.send(Command::AddWebFont(family, src, sender)).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exit(&self) {
|
pub fn exit(&self) {
|
||||||
let (response_chan, response_port) = channel();
|
let (response_chan, response_port) = ipc::channel().unwrap();
|
||||||
self.chan.send(Command::Exit(response_chan)).unwrap();
|
self.chan.send(Command::Exit(response_chan)).unwrap();
|
||||||
response_port.recv().unwrap();
|
response_port.recv().unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ use style::computed_values::{font_stretch, font_weight};
|
||||||
/// to be expanded or refactored when we support more of the font styling parameters.
|
/// to be expanded or refactored when we support more of the font styling parameters.
|
||||||
///
|
///
|
||||||
/// NB: If you change this, you will need to update `style::properties::compute_font_hash()`.
|
/// NB: If you change this, you will need to update `style::properties::compute_font_hash()`.
|
||||||
#[derive(Clone, Copy, Eq, Hash)]
|
#[derive(Clone, Copy, Eq, Hash, Deserialize, Serialize)]
|
||||||
pub struct FontTemplateDescriptor {
|
pub struct FontTemplateDescriptor {
|
||||||
pub weight: font_weight::T,
|
pub weight: font_weight::T,
|
||||||
pub stretch: font_stretch::T,
|
pub stretch: font_stretch::T,
|
||||||
|
|
|
@ -36,8 +36,7 @@ use std::sync::mpsc::{Receiver, Select, Sender, channel};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use util::geometry::{ExpandToPixelBoundaries, ZERO_POINT};
|
use util::geometry::{ExpandToPixelBoundaries, ZERO_POINT};
|
||||||
use util::opts;
|
use util::opts;
|
||||||
use util::task::spawn_named;
|
use util::task;
|
||||||
use util::task::spawn_named_with_send_on_failure;
|
|
||||||
use util::task_state;
|
use util::task_state;
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Serialize, HeapSizeOf)]
|
#[derive(Clone, Deserialize, Serialize, HeapSizeOf)]
|
||||||
|
@ -255,9 +254,11 @@ impl<C> PaintTask<C> where C: PaintListener + Send + 'static {
|
||||||
failure_msg: Failure,
|
failure_msg: Failure,
|
||||||
time_profiler_chan: time::ProfilerChan,
|
time_profiler_chan: time::ProfilerChan,
|
||||||
mem_profiler_chan: mem::ProfilerChan,
|
mem_profiler_chan: mem::ProfilerChan,
|
||||||
shutdown_chan: Sender<()>) {
|
shutdown_chan: IpcSender<()>) {
|
||||||
let ConstellationChan(c) = constellation_chan.clone();
|
let ConstellationChan(c) = constellation_chan.clone();
|
||||||
spawn_named_with_send_on_failure(format!("PaintTask {:?}", id), task_state::PAINT, move || {
|
task::spawn_named_with_send_on_failure(format!("PaintTask {:?}", id),
|
||||||
|
task_state::PAINT,
|
||||||
|
move || {
|
||||||
{
|
{
|
||||||
// Ensures that the paint task and graphics context are destroyed before the
|
// Ensures that the paint task and graphics context are destroyed before the
|
||||||
// shutdown message.
|
// shutdown message.
|
||||||
|
@ -572,7 +573,7 @@ impl WorkerThreadProxy {
|
||||||
let (to_worker_sender, to_worker_receiver) = channel();
|
let (to_worker_sender, to_worker_receiver) = channel();
|
||||||
let font_cache_task = font_cache_task.clone();
|
let font_cache_task = font_cache_task.clone();
|
||||||
let time_profiler_chan = time_profiler_chan.clone();
|
let time_profiler_chan = time_profiler_chan.clone();
|
||||||
spawn_named("PaintWorker".to_owned(), move || {
|
task::spawn_named("PaintWorker".to_owned(), move || {
|
||||||
let mut worker_thread = WorkerThread::new(from_worker_sender,
|
let mut worker_thread = WorkerThread::new(from_worker_sender,
|
||||||
to_worker_receiver,
|
to_worker_receiver,
|
||||||
native_display,
|
native_display,
|
||||||
|
|
|
@ -70,7 +70,7 @@ use util::ipc::OptionalIpcSender;
|
||||||
use util::logical_geometry::LogicalPoint;
|
use util::logical_geometry::LogicalPoint;
|
||||||
use util::mem::HeapSizeOf;
|
use util::mem::HeapSizeOf;
|
||||||
use util::opts;
|
use util::opts;
|
||||||
use util::task::spawn_named_with_send_on_failure;
|
use util::task;
|
||||||
use util::task_state;
|
use util::task_state;
|
||||||
use util::workqueue::WorkQueue;
|
use util::workqueue::WorkQueue;
|
||||||
use wrapper::{LayoutDocument, LayoutElement, LayoutNode, ServoLayoutNode};
|
use wrapper::{LayoutDocument, LayoutElement, LayoutNode, ServoLayoutNode};
|
||||||
|
@ -137,13 +137,13 @@ pub struct LayoutTask {
|
||||||
font_cache_receiver: Receiver<()>,
|
font_cache_receiver: Receiver<()>,
|
||||||
|
|
||||||
/// The channel on which the font cache can send messages to us.
|
/// The channel on which the font cache can send messages to us.
|
||||||
font_cache_sender: Sender<()>,
|
font_cache_sender: IpcSender<()>,
|
||||||
|
|
||||||
/// The channel on which messages can be sent to the constellation.
|
/// The channel on which messages can be sent to the constellation.
|
||||||
constellation_chan: ConstellationChan<ConstellationMsg>,
|
constellation_chan: ConstellationChan<ConstellationMsg>,
|
||||||
|
|
||||||
/// The channel on which messages can be sent to the script task.
|
/// The channel on which messages can be sent to the script task.
|
||||||
script_chan: Sender<ConstellationControlMsg>,
|
script_chan: IpcSender<ConstellationControlMsg>,
|
||||||
|
|
||||||
/// The channel on which messages can be sent to the painting task.
|
/// The channel on which messages can be sent to the painting task.
|
||||||
paint_chan: OptionalIpcSender<LayoutToPaintMsg>,
|
paint_chan: OptionalIpcSender<LayoutToPaintMsg>,
|
||||||
|
@ -219,17 +219,18 @@ impl LayoutTaskFactory for LayoutTask {
|
||||||
pipeline_port: IpcReceiver<LayoutControlMsg>,
|
pipeline_port: IpcReceiver<LayoutControlMsg>,
|
||||||
constellation_chan: ConstellationChan<ConstellationMsg>,
|
constellation_chan: ConstellationChan<ConstellationMsg>,
|
||||||
failure_msg: Failure,
|
failure_msg: Failure,
|
||||||
script_chan: Sender<ConstellationControlMsg>,
|
script_chan: IpcSender<ConstellationControlMsg>,
|
||||||
paint_chan: OptionalIpcSender<LayoutToPaintMsg>,
|
paint_chan: OptionalIpcSender<LayoutToPaintMsg>,
|
||||||
image_cache_task: ImageCacheTask,
|
image_cache_task: ImageCacheTask,
|
||||||
font_cache_task: FontCacheTask,
|
font_cache_task: FontCacheTask,
|
||||||
time_profiler_chan: time::ProfilerChan,
|
time_profiler_chan: time::ProfilerChan,
|
||||||
mem_profiler_chan: mem::ProfilerChan,
|
mem_profiler_chan: mem::ProfilerChan,
|
||||||
shutdown_chan: Sender<()>) {
|
shutdown_chan: IpcSender<()>,
|
||||||
|
content_process_shutdown_chan: IpcSender<()>) {
|
||||||
let ConstellationChan(con_chan) = constellation_chan.clone();
|
let ConstellationChan(con_chan) = constellation_chan.clone();
|
||||||
spawn_named_with_send_on_failure(format!("LayoutTask {:?}", id),
|
task::spawn_named_with_send_on_failure(format!("LayoutTask {:?}", id),
|
||||||
task_state::LAYOUT,
|
task_state::LAYOUT,
|
||||||
move || {
|
move || {
|
||||||
{ // Ensures layout task is destroyed before we send shutdown message
|
{ // Ensures layout task is destroyed before we send shutdown message
|
||||||
let sender = chan.sender();
|
let sender = chan.sender();
|
||||||
let layout = LayoutTask::new(id,
|
let layout = LayoutTask::new(id,
|
||||||
|
@ -250,7 +251,8 @@ impl LayoutTaskFactory for LayoutTask {
|
||||||
layout.start();
|
layout.start();
|
||||||
}, reporter_name, sender, Msg::CollectReports);
|
}, reporter_name, sender, Msg::CollectReports);
|
||||||
}
|
}
|
||||||
shutdown_chan.send(()).unwrap();
|
let _ = shutdown_chan.send(());
|
||||||
|
let _ = content_process_shutdown_chan.send(());
|
||||||
}, ConstellationMsg::Failure(failure_msg), con_chan);
|
}, ConstellationMsg::Failure(failure_msg), con_chan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -318,12 +320,12 @@ impl<'a, 'b: 'a> RwData<'a, 'b> {
|
||||||
fn add_font_face_rules(stylesheet: &Stylesheet,
|
fn add_font_face_rules(stylesheet: &Stylesheet,
|
||||||
device: &Device,
|
device: &Device,
|
||||||
font_cache_task: &FontCacheTask,
|
font_cache_task: &FontCacheTask,
|
||||||
font_cache_sender: &Sender<()>,
|
font_cache_sender: &IpcSender<()>,
|
||||||
outstanding_web_fonts_counter: &Arc<AtomicUsize>) {
|
outstanding_web_fonts_counter: &Arc<AtomicUsize>) {
|
||||||
for font_face in stylesheet.effective_rules(&device).font_face() {
|
for font_face in stylesheet.effective_rules(&device).font_face() {
|
||||||
for source in &font_face.sources {
|
for source in &font_face.sources {
|
||||||
if opts::get().load_webfonts_synchronously {
|
if opts::get().load_webfonts_synchronously {
|
||||||
let (sender, receiver) = channel();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
font_cache_task.add_web_font(font_face.family.clone(),
|
font_cache_task.add_web_font(font_face.family.clone(),
|
||||||
(*source).clone(),
|
(*source).clone(),
|
||||||
sender);
|
sender);
|
||||||
|
@ -346,7 +348,7 @@ impl LayoutTask {
|
||||||
port: Receiver<Msg>,
|
port: Receiver<Msg>,
|
||||||
pipeline_port: IpcReceiver<LayoutControlMsg>,
|
pipeline_port: IpcReceiver<LayoutControlMsg>,
|
||||||
constellation_chan: ConstellationChan<ConstellationMsg>,
|
constellation_chan: ConstellationChan<ConstellationMsg>,
|
||||||
script_chan: Sender<ConstellationControlMsg>,
|
script_chan: IpcSender<ConstellationControlMsg>,
|
||||||
paint_chan: OptionalIpcSender<LayoutToPaintMsg>,
|
paint_chan: OptionalIpcSender<LayoutToPaintMsg>,
|
||||||
image_cache_task: ImageCacheTask,
|
image_cache_task: ImageCacheTask,
|
||||||
font_cache_task: FontCacheTask,
|
font_cache_task: FontCacheTask,
|
||||||
|
@ -375,7 +377,10 @@ impl LayoutTask {
|
||||||
let image_cache_receiver =
|
let image_cache_receiver =
|
||||||
ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_image_cache_receiver);
|
ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_image_cache_receiver);
|
||||||
|
|
||||||
let (font_cache_sender, font_cache_receiver) = channel();
|
// Ask the router to proxy IPC messages from the font cache task to the layout thread.
|
||||||
|
let (ipc_font_cache_sender, ipc_font_cache_receiver) = ipc::channel().unwrap();
|
||||||
|
let font_cache_receiver =
|
||||||
|
ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_font_cache_receiver);
|
||||||
|
|
||||||
let stylist = box Stylist::new(device);
|
let stylist = box Stylist::new(device);
|
||||||
let outstanding_web_fonts_counter = Arc::new(AtomicUsize::new(0));
|
let outstanding_web_fonts_counter = Arc::new(AtomicUsize::new(0));
|
||||||
|
@ -383,7 +388,7 @@ impl LayoutTask {
|
||||||
add_font_face_rules(stylesheet,
|
add_font_face_rules(stylesheet,
|
||||||
&stylist.device,
|
&stylist.device,
|
||||||
&font_cache_task,
|
&font_cache_task,
|
||||||
&font_cache_sender,
|
&ipc_font_cache_sender,
|
||||||
&outstanding_web_fonts_counter);
|
&outstanding_web_fonts_counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,7 +409,7 @@ impl LayoutTask {
|
||||||
image_cache_receiver: image_cache_receiver,
|
image_cache_receiver: image_cache_receiver,
|
||||||
image_cache_sender: ImageCacheChan(ipc_image_cache_sender),
|
image_cache_sender: ImageCacheChan(ipc_image_cache_sender),
|
||||||
font_cache_receiver: font_cache_receiver,
|
font_cache_receiver: font_cache_receiver,
|
||||||
font_cache_sender: font_cache_sender,
|
font_cache_sender: ipc_font_cache_sender,
|
||||||
canvas_layers_receiver: canvas_layers_receiver,
|
canvas_layers_receiver: canvas_layers_receiver,
|
||||||
canvas_layers_sender: canvas_layers_sender,
|
canvas_layers_sender: canvas_layers_sender,
|
||||||
parallel_traversal: parallel_traversal,
|
parallel_traversal: parallel_traversal,
|
||||||
|
@ -668,14 +673,13 @@ impl LayoutTask {
|
||||||
info.constellation_chan,
|
info.constellation_chan,
|
||||||
info.failure,
|
info.failure,
|
||||||
info.script_chan.clone(),
|
info.script_chan.clone(),
|
||||||
*info.paint_chan
|
info.paint_chan.to::<LayoutToPaintMsg>(),
|
||||||
.downcast::<OptionalIpcSender<LayoutToPaintMsg>>()
|
|
||||||
.unwrap(),
|
|
||||||
self.image_cache_task.clone(),
|
self.image_cache_task.clone(),
|
||||||
self.font_cache_task.clone(),
|
self.font_cache_task.clone(),
|
||||||
self.time_profiler_chan.clone(),
|
self.time_profiler_chan.clone(),
|
||||||
self.mem_profiler_chan.clone(),
|
self.mem_profiler_chan.clone(),
|
||||||
info.layout_shutdown_chan);
|
info.layout_shutdown_chan,
|
||||||
|
info.content_process_shutdown_chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enters a quiescent state in which no new messages will be processed until an `ExitNow` is
|
/// Enters a quiescent state in which no new messages will be processed until an `ExitNow` is
|
||||||
|
|
|
@ -29,7 +29,6 @@ use msg::constellation_msg::{ConstellationChan, Failure, PipelineId};
|
||||||
use net_traits::image_cache_task::ImageCacheTask;
|
use net_traits::image_cache_task::ImageCacheTask;
|
||||||
use profile_traits::{mem, time};
|
use profile_traits::{mem, time};
|
||||||
use script_traits::{LayoutControlMsg, ConstellationControlMsg, OpaqueScriptLayoutChannel};
|
use script_traits::{LayoutControlMsg, ConstellationControlMsg, OpaqueScriptLayoutChannel};
|
||||||
use std::sync::mpsc::Sender;
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use util::ipc::OptionalIpcSender;
|
use util::ipc::OptionalIpcSender;
|
||||||
|
|
||||||
|
@ -49,11 +48,12 @@ pub trait LayoutTaskFactory {
|
||||||
pipeline_port: IpcReceiver<LayoutControlMsg>,
|
pipeline_port: IpcReceiver<LayoutControlMsg>,
|
||||||
constellation_chan: ConstellationChan<ConstellationMsg>,
|
constellation_chan: ConstellationChan<ConstellationMsg>,
|
||||||
failure_msg: Failure,
|
failure_msg: Failure,
|
||||||
script_chan: Sender<ConstellationControlMsg>,
|
script_chan: IpcSender<ConstellationControlMsg>,
|
||||||
layout_to_paint_chan: OptionalIpcSender<LayoutToPaintMsg>,
|
layout_to_paint_chan: OptionalIpcSender<LayoutToPaintMsg>,
|
||||||
image_cache_task: ImageCacheTask,
|
image_cache_task: ImageCacheTask,
|
||||||
font_cache_task: FontCacheTask,
|
font_cache_task: FontCacheTask,
|
||||||
time_profiler_chan: time::ProfilerChan,
|
time_profiler_chan: time::ProfilerChan,
|
||||||
mem_profiler_chan: mem::ProfilerChan,
|
mem_profiler_chan: mem::ProfilerChan,
|
||||||
shutdown_chan: Sender<()>);
|
shutdown_chan: IpcSender<()>,
|
||||||
|
content_process_shutdown_chan: IpcSender<()>);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,13 +11,14 @@ use euclid::scale_factor::ScaleFactor;
|
||||||
use euclid::size::{Size2D, TypedSize2D};
|
use euclid::size::{Size2D, TypedSize2D};
|
||||||
use hyper::header::Headers;
|
use hyper::header::Headers;
|
||||||
use hyper::method::Method;
|
use hyper::method::Method;
|
||||||
use ipc_channel::ipc::{IpcSender, IpcSharedMemory};
|
use ipc_channel::ipc::{self, IpcReceiver, IpcSender, IpcSharedMemory};
|
||||||
use layers::geometry::DevicePixel;
|
use layers::geometry::DevicePixel;
|
||||||
use offscreen_gl_context::GLContextAttributes;
|
use offscreen_gl_context::GLContextAttributes;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::mpsc::{Receiver, Sender, channel};
|
use std::sync::mpsc::channel;
|
||||||
use style_traits::viewport::ViewportConstraints;
|
use style_traits::viewport::ViewportConstraints;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use util::cursor::Cursor;
|
use util::cursor::Cursor;
|
||||||
|
@ -25,16 +26,17 @@ use util::geometry::{PagePx, ViewportPx};
|
||||||
use util::mem::HeapSizeOf;
|
use util::mem::HeapSizeOf;
|
||||||
use webdriver_msg::{LoadStatus, WebDriverScriptCommand};
|
use webdriver_msg::{LoadStatus, WebDriverScriptCommand};
|
||||||
|
|
||||||
pub struct ConstellationChan<T>(pub Sender<T>);
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct ConstellationChan<T: Deserialize + Serialize>(pub IpcSender<T>);
|
||||||
|
|
||||||
impl<T> ConstellationChan<T> {
|
impl<T: Deserialize + Serialize> ConstellationChan<T> {
|
||||||
pub fn new() -> (Receiver<T>, ConstellationChan<T>) {
|
pub fn new() -> (IpcReceiver<T>, ConstellationChan<T>) {
|
||||||
let (chan, port) = channel();
|
let (chan, port) = ipc::channel().unwrap();
|
||||||
(port, ConstellationChan(chan))
|
(port, ConstellationChan(chan))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Clone for ConstellationChan<T> {
|
impl<T: Serialize + Deserialize> Clone for ConstellationChan<T> {
|
||||||
fn clone(&self) -> ConstellationChan<T> {
|
fn clone(&self) -> ConstellationChan<T> {
|
||||||
ConstellationChan(self.0.clone())
|
ConstellationChan(self.0.clone())
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,6 +100,7 @@ impl Formattable for ProfilerCategory {
|
||||||
ProfilerCategory::ScriptUpdateReplacedElement => "Script Update Replaced Element",
|
ProfilerCategory::ScriptUpdateReplacedElement => "Script Update Replaced Element",
|
||||||
ProfilerCategory::ScriptSetViewport => "Script Set Viewport",
|
ProfilerCategory::ScriptSetViewport => "Script Set Viewport",
|
||||||
ProfilerCategory::ScriptTimerEvent => "Script Timer Event",
|
ProfilerCategory::ScriptTimerEvent => "Script Timer Event",
|
||||||
|
ProfilerCategory::ScriptStylesheetLoad => "Script Stylesheet Load",
|
||||||
ProfilerCategory::ScriptWebSocketEvent => "Script Web Socket Event",
|
ProfilerCategory::ScriptWebSocketEvent => "Script Web Socket Event",
|
||||||
ProfilerCategory::ScriptWorkerEvent => "Script Worker Event",
|
ProfilerCategory::ScriptWorkerEvent => "Script Worker Event",
|
||||||
ProfilerCategory::ApplicationHeartbeat => "Application Heartbeat",
|
ProfilerCategory::ApplicationHeartbeat => "Application Heartbeat",
|
||||||
|
|
|
@ -25,7 +25,7 @@ impl<T> OpaqueSender<T> for Sender<T> {
|
||||||
|
|
||||||
/// Front-end representation of the profiler used to communicate with the
|
/// Front-end representation of the profiler used to communicate with the
|
||||||
/// profiler.
|
/// profiler.
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
pub struct ProfilerChan(pub IpcSender<ProfilerMsg>);
|
pub struct ProfilerChan(pub IpcSender<ProfilerMsg>);
|
||||||
|
|
||||||
impl ProfilerChan {
|
impl ProfilerChan {
|
||||||
|
|
|
@ -60,15 +60,16 @@ pub enum ProfilerCategory {
|
||||||
ScriptDevtoolsMsg,
|
ScriptDevtoolsMsg,
|
||||||
ScriptDocumentEvent,
|
ScriptDocumentEvent,
|
||||||
ScriptDomEvent,
|
ScriptDomEvent,
|
||||||
|
ScriptEvent,
|
||||||
ScriptFileRead,
|
ScriptFileRead,
|
||||||
ScriptImageCacheMsg,
|
ScriptImageCacheMsg,
|
||||||
ScriptInputEvent,
|
ScriptInputEvent,
|
||||||
ScriptNetworkEvent,
|
ScriptNetworkEvent,
|
||||||
ScriptResize,
|
ScriptResize,
|
||||||
ScriptEvent,
|
|
||||||
ScriptUpdateReplacedElement,
|
|
||||||
ScriptSetViewport,
|
ScriptSetViewport,
|
||||||
ScriptTimerEvent,
|
ScriptTimerEvent,
|
||||||
|
ScriptStylesheetLoad,
|
||||||
|
ScriptUpdateReplacedElement,
|
||||||
ScriptWebSocketEvent,
|
ScriptWebSocketEvent,
|
||||||
ScriptWorkerEvent,
|
ScriptWorkerEvent,
|
||||||
ApplicationHeartbeat,
|
ApplicationHeartbeat,
|
||||||
|
|
|
@ -53,7 +53,7 @@ use js::jsval::JSVal;
|
||||||
use js::rust::Runtime;
|
use js::rust::Runtime;
|
||||||
use layout_interface::{LayoutChan, LayoutRPC};
|
use layout_interface::{LayoutChan, LayoutRPC};
|
||||||
use libc;
|
use libc;
|
||||||
use msg::constellation_msg::ConstellationChan;
|
use msg::constellation_msg::{ConstellationChan, ScriptMsg};
|
||||||
use msg::constellation_msg::{PipelineId, SubpageId, WindowSizeData, WorkerId};
|
use msg::constellation_msg::{PipelineId, SubpageId, WindowSizeData, WorkerId};
|
||||||
use net_traits::Metadata;
|
use net_traits::Metadata;
|
||||||
use net_traits::image::base::Image;
|
use net_traits::image::base::Image;
|
||||||
|
@ -275,7 +275,6 @@ no_jsmanaged_fields!(WorkerId);
|
||||||
no_jsmanaged_fields!(QuirksMode);
|
no_jsmanaged_fields!(QuirksMode);
|
||||||
no_jsmanaged_fields!(Runtime);
|
no_jsmanaged_fields!(Runtime);
|
||||||
no_jsmanaged_fields!(Headers, Method);
|
no_jsmanaged_fields!(Headers, Method);
|
||||||
no_jsmanaged_fields!(ConstellationChan<ConstellationMsg>);
|
|
||||||
no_jsmanaged_fields!(LayoutChan);
|
no_jsmanaged_fields!(LayoutChan);
|
||||||
no_jsmanaged_fields!(WindowProxyHandler);
|
no_jsmanaged_fields!(WindowProxyHandler);
|
||||||
no_jsmanaged_fields!(UntrustedNodeAddress);
|
no_jsmanaged_fields!(UntrustedNodeAddress);
|
||||||
|
@ -299,6 +298,13 @@ no_jsmanaged_fields!(AttrIdentifier);
|
||||||
no_jsmanaged_fields!(AttrValue);
|
no_jsmanaged_fields!(AttrValue);
|
||||||
no_jsmanaged_fields!(ElementSnapshot);
|
no_jsmanaged_fields!(ElementSnapshot);
|
||||||
|
|
||||||
|
impl JSTraceable for ConstellationChan<ScriptMsg> {
|
||||||
|
#[inline]
|
||||||
|
fn trace(&self, _trc: *mut JSTracer) {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl JSTraceable for Box<ScriptChan + Send> {
|
impl JSTraceable for Box<ScriptChan + Send> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn trace(&self, _trc: *mut JSTracer) {
|
fn trace(&self, _trc: *mut JSTracer) {
|
||||||
|
|
|
@ -29,6 +29,8 @@ use string_cache::Atom;
|
||||||
use style::animation::PropertyAnimation;
|
use style::animation::PropertyAnimation;
|
||||||
use style::stylesheets::Stylesheet;
|
use style::stylesheets::Stylesheet;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
use util::ipc::OptionalOpaqueIpcSender;
|
||||||
|
|
||||||
pub use dom::node::TrustedNodeAddress;
|
pub use dom::node::TrustedNodeAddress;
|
||||||
|
|
||||||
/// Asynchronous messages that script can send to layout.
|
/// Asynchronous messages that script can send to layout.
|
||||||
|
@ -254,8 +256,9 @@ pub struct NewLayoutTaskInfo {
|
||||||
pub pipeline_port: IpcReceiver<LayoutControlMsg>,
|
pub pipeline_port: IpcReceiver<LayoutControlMsg>,
|
||||||
pub constellation_chan: ConstellationChan<ConstellationMsg>,
|
pub constellation_chan: ConstellationChan<ConstellationMsg>,
|
||||||
pub failure: Failure,
|
pub failure: Failure,
|
||||||
pub script_chan: Sender<ConstellationControlMsg>,
|
pub script_chan: IpcSender<ConstellationControlMsg>,
|
||||||
pub image_cache_task: ImageCacheTask,
|
pub image_cache_task: ImageCacheTask,
|
||||||
pub paint_chan: Box<Any + Send>,
|
pub paint_chan: OptionalOpaqueIpcSender,
|
||||||
pub layout_shutdown_chan: Sender<()>,
|
pub layout_shutdown_chan: IpcSender<()>,
|
||||||
|
pub content_process_shutdown_chan: IpcSender<()>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ use time::{Tm, now};
|
||||||
use url::{Url, UrlParser};
|
use url::{Url, UrlParser};
|
||||||
use util::opts;
|
use util::opts;
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
use util::task::spawn_named_with_send_on_failure;
|
use util::task;
|
||||||
use util::task_state;
|
use util::task_state;
|
||||||
use webdriver_handlers;
|
use webdriver_handlers;
|
||||||
|
|
||||||
|
@ -232,8 +232,9 @@ pub enum ScriptTaskEventCategory {
|
||||||
Resize,
|
Resize,
|
||||||
ScriptEvent,
|
ScriptEvent,
|
||||||
TimerEvent,
|
TimerEvent,
|
||||||
UpdateReplacedElement,
|
|
||||||
SetViewport,
|
SetViewport,
|
||||||
|
StylesheetLoad,
|
||||||
|
UpdateReplacedElement,
|
||||||
WebSocketEvent,
|
WebSocketEvent,
|
||||||
WorkerEvent,
|
WorkerEvent,
|
||||||
}
|
}
|
||||||
|
@ -396,7 +397,7 @@ pub struct ScriptTask {
|
||||||
chan: MainThreadScriptChan,
|
chan: MainThreadScriptChan,
|
||||||
|
|
||||||
/// A channel to hand out to tasks that need to respond to a message from the script task.
|
/// A channel to hand out to tasks that need to respond to a message from the script task.
|
||||||
control_chan: Sender<ConstellationControlMsg>,
|
control_chan: IpcSender<ConstellationControlMsg>,
|
||||||
|
|
||||||
/// The port on which the constellation and layout tasks can communicate with the
|
/// The port on which the constellation and layout tasks can communicate with the
|
||||||
/// script task.
|
/// script task.
|
||||||
|
@ -438,6 +439,8 @@ pub struct ScriptTask {
|
||||||
scheduler_chan: IpcSender<TimerEventRequest>,
|
scheduler_chan: IpcSender<TimerEventRequest>,
|
||||||
timer_event_chan: Sender<TimerEvent>,
|
timer_event_chan: Sender<TimerEvent>,
|
||||||
timer_event_port: Receiver<TimerEvent>,
|
timer_event_port: Receiver<TimerEvent>,
|
||||||
|
|
||||||
|
content_process_shutdown_chan: IpcSender<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// In the event of task failure, all data on the stack runs its destructor. However, there
|
/// In the event of task failure, all data on the stack runs its destructor. However, there
|
||||||
|
@ -484,7 +487,8 @@ impl ScriptTaskFactory for ScriptTask {
|
||||||
ScriptLayoutChan::new(chan, port)
|
ScriptLayoutChan::new(chan, port)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone_layout_channel(_phantom: Option<&mut ScriptTask>, pair: &OpaqueScriptLayoutChannel) -> Box<Any + Send> {
|
fn clone_layout_channel(_phantom: Option<&mut ScriptTask>, pair: &OpaqueScriptLayoutChannel)
|
||||||
|
-> Box<Any + Send> {
|
||||||
box pair.sender() as Box<Any + Send>
|
box pair.sender() as Box<Any + Send>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,9 +500,10 @@ impl ScriptTaskFactory for ScriptTask {
|
||||||
let (script_chan, script_port) = channel();
|
let (script_chan, script_port) = channel();
|
||||||
let layout_chan = LayoutChan(layout_chan.sender());
|
let layout_chan = LayoutChan(layout_chan.sender());
|
||||||
let failure_info = state.failure_info;
|
let failure_info = state.failure_info;
|
||||||
spawn_named_with_send_on_failure(format!("ScriptTask {:?}", state.id), task_state::SCRIPT, move || {
|
task::spawn_named_with_send_on_failure(format!("ScriptTask {:?}", state.id),
|
||||||
|
task_state::SCRIPT,
|
||||||
|
move || {
|
||||||
PipelineNamespace::install(state.pipeline_namespace_id);
|
PipelineNamespace::install(state.pipeline_namespace_id);
|
||||||
|
|
||||||
let roots = RootCollection::new();
|
let roots = RootCollection::new();
|
||||||
let _stack_roots_tls = StackRootTLS::new(&roots);
|
let _stack_roots_tls = StackRootTLS::new(&roots);
|
||||||
let chan = MainThreadScriptChan(script_chan);
|
let chan = MainThreadScriptChan(script_chan);
|
||||||
|
@ -524,6 +529,7 @@ impl ScriptTaskFactory for ScriptTask {
|
||||||
let reporter_name = format!("script-reporter-{}", id);
|
let reporter_name = format!("script-reporter-{}", id);
|
||||||
mem_profiler_chan.run_with_memory_reporting(|| {
|
mem_profiler_chan.run_with_memory_reporting(|| {
|
||||||
script_task.start();
|
script_task.start();
|
||||||
|
let _ = script_task.content_process_shutdown_chan.send(());
|
||||||
}, reporter_name, channel_for_reporter, CommonScriptMsg::CollectReports);
|
}, reporter_name, channel_for_reporter, CommonScriptMsg::CollectReports);
|
||||||
|
|
||||||
// This must always be the very last operation performed before the task completes
|
// This must always be the very last operation performed before the task completes
|
||||||
|
@ -636,6 +642,9 @@ impl ScriptTask {
|
||||||
|
|
||||||
let (timer_event_chan, timer_event_port) = channel();
|
let (timer_event_chan, timer_event_port) = channel();
|
||||||
|
|
||||||
|
// Ask the router to proxy IPC messages from the control port to us.
|
||||||
|
let control_port = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(state.control_port);
|
||||||
|
|
||||||
ScriptTask {
|
ScriptTask {
|
||||||
page: DOMRefCell::new(None),
|
page: DOMRefCell::new(None),
|
||||||
incomplete_loads: DOMRefCell::new(vec!()),
|
incomplete_loads: DOMRefCell::new(vec!()),
|
||||||
|
@ -650,7 +659,7 @@ impl ScriptTask {
|
||||||
port: port,
|
port: port,
|
||||||
chan: chan,
|
chan: chan,
|
||||||
control_chan: state.control_chan,
|
control_chan: state.control_chan,
|
||||||
control_port: state.control_port,
|
control_port: control_port,
|
||||||
constellation_chan: state.constellation_chan,
|
constellation_chan: state.constellation_chan,
|
||||||
compositor: DOMRefCell::new(state.compositor),
|
compositor: DOMRefCell::new(state.compositor),
|
||||||
time_profiler_chan: state.time_profiler_chan,
|
time_profiler_chan: state.time_profiler_chan,
|
||||||
|
@ -667,6 +676,8 @@ impl ScriptTask {
|
||||||
scheduler_chan: state.scheduler_chan,
|
scheduler_chan: state.scheduler_chan,
|
||||||
timer_event_chan: timer_event_chan,
|
timer_event_chan: timer_event_chan,
|
||||||
timer_event_port: timer_event_port,
|
timer_event_port: timer_event_port,
|
||||||
|
|
||||||
|
content_process_shutdown_chan: state.content_process_shutdown_chan,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -940,7 +951,10 @@ impl ScriptTask {
|
||||||
ScriptTaskEventCategory::NetworkEvent => ProfilerCategory::ScriptNetworkEvent,
|
ScriptTaskEventCategory::NetworkEvent => ProfilerCategory::ScriptNetworkEvent,
|
||||||
ScriptTaskEventCategory::Resize => ProfilerCategory::ScriptResize,
|
ScriptTaskEventCategory::Resize => ProfilerCategory::ScriptResize,
|
||||||
ScriptTaskEventCategory::ScriptEvent => ProfilerCategory::ScriptEvent,
|
ScriptTaskEventCategory::ScriptEvent => ProfilerCategory::ScriptEvent,
|
||||||
ScriptTaskEventCategory::UpdateReplacedElement => ProfilerCategory::ScriptUpdateReplacedElement,
|
ScriptTaskEventCategory::UpdateReplacedElement => {
|
||||||
|
ProfilerCategory::ScriptUpdateReplacedElement
|
||||||
|
}
|
||||||
|
ScriptTaskEventCategory::StylesheetLoad => ProfilerCategory::ScriptStylesheetLoad,
|
||||||
ScriptTaskEventCategory::SetViewport => ProfilerCategory::ScriptSetViewport,
|
ScriptTaskEventCategory::SetViewport => ProfilerCategory::ScriptSetViewport,
|
||||||
ScriptTaskEventCategory::TimerEvent => ProfilerCategory::ScriptTimerEvent,
|
ScriptTaskEventCategory::TimerEvent => ProfilerCategory::ScriptTimerEvent,
|
||||||
ScriptTaskEventCategory::WebSocketEvent => ProfilerCategory::ScriptWebSocketEvent,
|
ScriptTaskEventCategory::WebSocketEvent => ProfilerCategory::ScriptWebSocketEvent,
|
||||||
|
@ -1185,6 +1199,7 @@ impl ScriptTask {
|
||||||
failure,
|
failure,
|
||||||
pipeline_port,
|
pipeline_port,
|
||||||
layout_shutdown_chan,
|
layout_shutdown_chan,
|
||||||
|
content_process_shutdown_chan,
|
||||||
} = new_layout_info;
|
} = new_layout_info;
|
||||||
|
|
||||||
let layout_pair = ScriptTask::create_layout_channel(None::<&mut ScriptTask>);
|
let layout_pair = ScriptTask::create_layout_channel(None::<&mut ScriptTask>);
|
||||||
|
@ -1204,6 +1219,7 @@ impl ScriptTask {
|
||||||
script_chan: self.control_chan.clone(),
|
script_chan: self.control_chan.clone(),
|
||||||
image_cache_task: self.image_cache_task.clone(),
|
image_cache_task: self.image_cache_task.clone(),
|
||||||
layout_shutdown_chan: layout_shutdown_chan,
|
layout_shutdown_chan: layout_shutdown_chan,
|
||||||
|
content_process_shutdown_chan: content_process_shutdown_chan,
|
||||||
};
|
};
|
||||||
|
|
||||||
let page = self.root_page();
|
let page = self.root_page();
|
||||||
|
|
|
@ -41,7 +41,7 @@ use net_traits::image_cache_task::ImageCacheTask;
|
||||||
use net_traits::storage_task::StorageTask;
|
use net_traits::storage_task::StorageTask;
|
||||||
use profile_traits::mem;
|
use profile_traits::mem;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::sync::mpsc::{Receiver, Sender};
|
use util::ipc::OptionalOpaqueIpcSender;
|
||||||
use util::mem::HeapSizeOf;
|
use util::mem::HeapSizeOf;
|
||||||
|
|
||||||
/// The address of a node. Layout sends these back. They must be validated via
|
/// The address of a node. Layout sends these back. They must be validated via
|
||||||
|
@ -68,6 +68,7 @@ pub enum LayoutControlMsg {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The initial data associated with a newly-created framed pipeline.
|
/// The initial data associated with a newly-created framed pipeline.
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
pub struct NewLayoutInfo {
|
pub struct NewLayoutInfo {
|
||||||
/// Id of the parent of this new pipeline.
|
/// Id of the parent of this new pipeline.
|
||||||
pub containing_pipeline_id: PipelineId,
|
pub containing_pipeline_id: PipelineId,
|
||||||
|
@ -77,21 +78,21 @@ pub struct NewLayoutInfo {
|
||||||
pub subpage_id: SubpageId,
|
pub subpage_id: SubpageId,
|
||||||
/// Network request data which will be initiated by the script task.
|
/// Network request data which will be initiated by the script task.
|
||||||
pub load_data: LoadData,
|
pub load_data: LoadData,
|
||||||
/// The paint channel, cast to `Box<Any>`.
|
/// The paint channel, cast to `OptionalOpaqueIpcSender`. This is really an
|
||||||
///
|
/// `Sender<LayoutToPaintMsg>`.
|
||||||
/// TODO(pcwalton): When we convert this to use IPC, this will need to become an
|
pub paint_chan: OptionalOpaqueIpcSender,
|
||||||
/// `IpcAnySender`.
|
|
||||||
pub paint_chan: Box<Any + Send>,
|
|
||||||
/// Information on what to do on task failure.
|
/// Information on what to do on task failure.
|
||||||
pub failure: Failure,
|
pub failure: Failure,
|
||||||
/// A port on which layout can receive messages from the pipeline.
|
/// A port on which layout can receive messages from the pipeline.
|
||||||
pub pipeline_port: IpcReceiver<LayoutControlMsg>,
|
pub pipeline_port: IpcReceiver<LayoutControlMsg>,
|
||||||
/// A shutdown channel so that layout can notify others when it's done.
|
/// A shutdown channel so that layout can notify others when it's done.
|
||||||
pub layout_shutdown_chan: Sender<()>,
|
pub layout_shutdown_chan: IpcSender<()>,
|
||||||
|
/// A shutdown channel so that layout can tell the content process to shut down when it's done.
|
||||||
|
pub content_process_shutdown_chan: IpcSender<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Used to determine if a script has any pending asynchronous activity.
|
/// Used to determine if a script has any pending asynchronous activity.
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Deserialize, Serialize)]
|
||||||
pub enum ScriptState {
|
pub enum ScriptState {
|
||||||
/// The document has been loaded.
|
/// The document has been loaded.
|
||||||
DocumentLoaded,
|
DocumentLoaded,
|
||||||
|
@ -100,6 +101,7 @@ pub enum ScriptState {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Messages sent from the constellation or layout to the script task.
|
/// Messages sent from the constellation or layout to the script task.
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
pub enum ConstellationControlMsg {
|
pub enum ConstellationControlMsg {
|
||||||
/// Gives a channel and ID to a layout task, as well as the ID of that layout's parent
|
/// Gives a channel and ID to a layout task, as well as the ID of that layout's parent
|
||||||
AttachLayout(NewLayoutInfo),
|
AttachLayout(NewLayoutInfo),
|
||||||
|
@ -135,11 +137,11 @@ pub enum ConstellationControlMsg {
|
||||||
/// reflowed.
|
/// reflowed.
|
||||||
WebFontLoaded(PipelineId),
|
WebFontLoaded(PipelineId),
|
||||||
/// Get the current state of the script task for a given pipeline.
|
/// Get the current state of the script task for a given pipeline.
|
||||||
GetCurrentState(Sender<ScriptState>, PipelineId),
|
GetCurrentState(IpcSender<ScriptState>, PipelineId),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The mouse button involved in the event.
|
/// The mouse button involved in the event.
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
|
||||||
pub enum MouseButton {
|
pub enum MouseButton {
|
||||||
/// The left mouse button.
|
/// The left mouse button.
|
||||||
Left,
|
Left,
|
||||||
|
@ -150,7 +152,7 @@ pub enum MouseButton {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The type of input represented by a multi-touch event.
|
/// The type of input represented by a multi-touch event.
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
|
||||||
pub enum TouchEventType {
|
pub enum TouchEventType {
|
||||||
/// A new touch point came in contact with the screen.
|
/// A new touch point came in contact with the screen.
|
||||||
Down,
|
Down,
|
||||||
|
@ -165,10 +167,11 @@ pub enum TouchEventType {
|
||||||
/// An opaque identifier for a touch point.
|
/// An opaque identifier for a touch point.
|
||||||
///
|
///
|
||||||
/// http://w3c.github.io/touch-events/#widl-Touch-identifier
|
/// http://w3c.github.io/touch-events/#widl-Touch-identifier
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)]
|
||||||
pub struct TouchId(pub i32);
|
pub struct TouchId(pub i32);
|
||||||
|
|
||||||
/// Events from the compositor that the script task needs to know about
|
/// Events from the compositor that the script task needs to know about
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
pub enum CompositorEvent {
|
pub enum CompositorEvent {
|
||||||
/// The window was resized.
|
/// The window was resized.
|
||||||
ResizeEvent(WindowSizeData),
|
ResizeEvent(WindowSizeData),
|
||||||
|
@ -250,9 +253,9 @@ pub struct InitialScriptState {
|
||||||
/// The compositor.
|
/// The compositor.
|
||||||
pub compositor: IpcSender<ScriptToCompositorMsg>,
|
pub compositor: IpcSender<ScriptToCompositorMsg>,
|
||||||
/// A channel with which messages can be sent to us (the script task).
|
/// A channel with which messages can be sent to us (the script task).
|
||||||
pub control_chan: Sender<ConstellationControlMsg>,
|
pub control_chan: IpcSender<ConstellationControlMsg>,
|
||||||
/// A port on which messages sent by the constellation to script can be received.
|
/// A port on which messages sent by the constellation to script can be received.
|
||||||
pub control_port: Receiver<ConstellationControlMsg>,
|
pub control_port: IpcReceiver<ConstellationControlMsg>,
|
||||||
/// A channel on which messages can be sent to the constellation from script.
|
/// A channel on which messages can be sent to the constellation from script.
|
||||||
pub constellation_chan: ConstellationChan<ConstellationMsg>,
|
pub constellation_chan: ConstellationChan<ConstellationMsg>,
|
||||||
/// A channel to schedule timer events.
|
/// A channel to schedule timer events.
|
||||||
|
@ -275,8 +278,14 @@ pub struct InitialScriptState {
|
||||||
pub window_size: Option<WindowSizeData>,
|
pub window_size: Option<WindowSizeData>,
|
||||||
/// The ID of the pipeline namespace for this script thread.
|
/// The ID of the pipeline namespace for this script thread.
|
||||||
pub pipeline_namespace_id: PipelineNamespaceId,
|
pub pipeline_namespace_id: PipelineNamespaceId,
|
||||||
|
/// A ping will be sent on this channel once the script thread shuts down.
|
||||||
|
pub content_process_shutdown_chan: IpcSender<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Encapsulates external communication with the script task.
|
||||||
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
|
pub struct ScriptControlChan(pub IpcSender<ConstellationControlMsg>);
|
||||||
|
|
||||||
/// This trait allows creating a `ScriptTask` without depending on the `script`
|
/// This trait allows creating a `ScriptTask` without depending on the `script`
|
||||||
/// crate.
|
/// crate.
|
||||||
pub trait ScriptTaskFactory {
|
pub trait ScriptTaskFactory {
|
||||||
|
|
16
components/servo/Cargo.lock
generated
16
components/servo/Cargo.lock
generated
|
@ -11,11 +11,13 @@ dependencies = [
|
||||||
"devtools_traits 0.0.1",
|
"devtools_traits 0.0.1",
|
||||||
"env_logger 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gaol 0.0.1 (git+https://github.com/pcwalton/gaol)",
|
||||||
"gfx 0.0.1",
|
"gfx 0.0.1",
|
||||||
"gfx_tests 0.0.1",
|
"gfx_tests 0.0.1",
|
||||||
"gleam 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gleam 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glutin_app 0.0.1",
|
"glutin_app 0.0.1",
|
||||||
"image 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"image 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)",
|
||||||
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
|
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
|
||||||
"layout 0.0.1",
|
"layout 0.0.1",
|
||||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -261,6 +263,7 @@ dependencies = [
|
||||||
"core-text 0.1.0 (git+https://github.com/servo/core-text-rs)",
|
"core-text 0.1.0 (git+https://github.com/servo/core-text-rs)",
|
||||||
"devtools_traits 0.0.1",
|
"devtools_traits 0.0.1",
|
||||||
"euclid 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gaol 0.0.1 (git+https://github.com/pcwalton/gaol)",
|
||||||
"gfx 0.0.1",
|
"gfx 0.0.1",
|
||||||
"gfx_traits 0.0.1",
|
"gfx_traits 0.0.1",
|
||||||
"gleam 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gleam 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -268,6 +271,7 @@ dependencies = [
|
||||||
"ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)",
|
"ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)",
|
||||||
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
|
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
|
||||||
"layout_traits 0.0.1",
|
"layout_traits 0.0.1",
|
||||||
|
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"msg 0.0.1",
|
"msg 0.0.1",
|
||||||
"net_traits 0.0.1",
|
"net_traits 0.0.1",
|
||||||
|
@ -276,6 +280,8 @@ dependencies = [
|
||||||
"plugins 0.0.1",
|
"plugins 0.0.1",
|
||||||
"profile_traits 0.0.1",
|
"profile_traits 0.0.1",
|
||||||
"script_traits 0.0.1",
|
"script_traits 0.0.1",
|
||||||
|
"serde 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde_macros 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"style_traits 0.0.1",
|
"style_traits 0.0.1",
|
||||||
"time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -600,6 +606,16 @@ dependencies = [
|
||||||
"mac 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mac 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gaol"
|
||||||
|
version = "0.0.1"
|
||||||
|
source = "git+https://github.com/pcwalton/gaol#71865ff8a1824cbc1cbee4d388d56c5ba1b5ffc2"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gcc"
|
name = "gcc"
|
||||||
version = "0.3.16"
|
version = "0.3.16"
|
||||||
|
|
|
@ -129,6 +129,12 @@ features = [ "serde_serialization" ]
|
||||||
version = "0.3"
|
version = "0.3"
|
||||||
features = ["plugins"]
|
features = ["plugins"]
|
||||||
|
|
||||||
|
[dependencies.gaol]
|
||||||
|
git = "https://github.com/pcwalton/gaol"
|
||||||
|
|
||||||
|
[dependencies.ipc-channel]
|
||||||
|
git = "https://github.com/pcwalton/ipc-channel"
|
||||||
|
|
||||||
[dependencies.layers]
|
[dependencies.layers]
|
||||||
git = "https://github.com/servo/rust-layers"
|
git = "https://github.com/servo/rust-layers"
|
||||||
features = ["plugins"]
|
features = ["plugins"]
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
// The `Browser` is fed events from a generic type that implements the
|
// The `Browser` is fed events from a generic type that implements the
|
||||||
// `WindowMethods` trait.
|
// `WindowMethods` trait.
|
||||||
|
|
||||||
|
extern crate gaol;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate util as _util;
|
extern crate util as _util;
|
||||||
|
|
||||||
|
@ -29,6 +31,7 @@ mod export {
|
||||||
extern crate euclid;
|
extern crate euclid;
|
||||||
extern crate gfx;
|
extern crate gfx;
|
||||||
extern crate gleam;
|
extern crate gleam;
|
||||||
|
extern crate ipc_channel;
|
||||||
extern crate layers;
|
extern crate layers;
|
||||||
extern crate layout;
|
extern crate layout;
|
||||||
extern crate msg;
|
extern crate msg;
|
||||||
|
@ -48,22 +51,25 @@ extern crate libc;
|
||||||
extern crate webdriver_server;
|
extern crate webdriver_server;
|
||||||
|
|
||||||
#[cfg(feature = "webdriver")]
|
#[cfg(feature = "webdriver")]
|
||||||
fn webdriver(port: u16, constellation: msg::constellation_msg::ConstellationChan<ConstellationMsg>) {
|
fn webdriver(port: u16, constellation: Sender<ConstellationMsg>) {
|
||||||
webdriver_server::start_server(port, constellation.clone());
|
webdriver_server::start_server(port, constellation);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "webdriver"))]
|
#[cfg(not(feature = "webdriver"))]
|
||||||
fn webdriver(_port: u16, _constellation: msg::constellation_msg::ConstellationChan<ConstellationMsg>) { }
|
fn webdriver(_port: u16, _constellation: Sender<ConstellationMsg>) { }
|
||||||
|
|
||||||
use compositing::CompositorEventListener;
|
use compositing::CompositorEventListener;
|
||||||
use compositing::compositor_task::InitialCompositorState;
|
use compositing::compositor_task::InitialCompositorState;
|
||||||
use compositing::constellation::InitialConstellationState;
|
use compositing::constellation::InitialConstellationState;
|
||||||
|
use compositing::pipeline::UnprivilegedPipelineContent;
|
||||||
|
use compositing::sandboxing;
|
||||||
use compositing::windowing::WindowEvent;
|
use compositing::windowing::WindowEvent;
|
||||||
use compositing::windowing::WindowMethods;
|
use compositing::windowing::WindowMethods;
|
||||||
use compositing::{CompositorProxy, CompositorTask, Constellation};
|
use compositing::{CompositorProxy, CompositorTask, Constellation};
|
||||||
|
use gaol::sandbox::{ChildSandbox, ChildSandboxMethods};
|
||||||
use gfx::font_cache_task::FontCacheTask;
|
use gfx::font_cache_task::FontCacheTask;
|
||||||
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
use msg::constellation_msg::CompositorMsg as ConstellationMsg;
|
use msg::constellation_msg::CompositorMsg as ConstellationMsg;
|
||||||
use msg::constellation_msg::ConstellationChan;
|
|
||||||
use net::image_cache_task::new_image_cache_task;
|
use net::image_cache_task::new_image_cache_task;
|
||||||
use net::resource_task::new_resource_task;
|
use net::resource_task::new_resource_task;
|
||||||
use net::storage_task::StorageTaskFactory;
|
use net::storage_task::StorageTaskFactory;
|
||||||
|
@ -86,6 +92,7 @@ pub use export::devtools_traits;
|
||||||
pub use export::euclid;
|
pub use export::euclid;
|
||||||
pub use export::gfx;
|
pub use export::gfx;
|
||||||
pub use export::gleam::gl;
|
pub use export::gleam::gl;
|
||||||
|
pub use export::ipc_channel;
|
||||||
pub use export::layers;
|
pub use export::layers;
|
||||||
pub use export::layout;
|
pub use export::layout;
|
||||||
pub use export::msg;
|
pub use export::msg;
|
||||||
|
@ -193,7 +200,7 @@ fn create_constellation(opts: opts::Opts,
|
||||||
time_profiler_chan: time::ProfilerChan,
|
time_profiler_chan: time::ProfilerChan,
|
||||||
mem_profiler_chan: mem::ProfilerChan,
|
mem_profiler_chan: mem::ProfilerChan,
|
||||||
devtools_chan: Option<Sender<devtools_traits::DevtoolsControlMsg>>,
|
devtools_chan: Option<Sender<devtools_traits::DevtoolsControlMsg>>,
|
||||||
supports_clipboard: bool) -> ConstellationChan<ConstellationMsg> {
|
supports_clipboard: bool) -> Sender<ConstellationMsg> {
|
||||||
let resource_task = new_resource_task(opts.user_agent.clone(), devtools_chan.clone());
|
let resource_task = new_resource_task(opts.user_agent.clone(), devtools_chan.clone());
|
||||||
|
|
||||||
let image_cache_task = new_image_cache_task(resource_task.clone());
|
let image_cache_task = new_image_cache_task(resource_task.clone());
|
||||||
|
@ -218,11 +225,33 @@ fn create_constellation(opts: opts::Opts,
|
||||||
// Send the URL command to the constellation.
|
// Send the URL command to the constellation.
|
||||||
match opts.url {
|
match opts.url {
|
||||||
Some(url) => {
|
Some(url) => {
|
||||||
let ConstellationChan(ref chan) = constellation_chan;
|
constellation_chan.send(ConstellationMsg::InitLoadUrl(url)).unwrap();
|
||||||
chan.send(ConstellationMsg::InitLoadUrl(url)).unwrap();
|
|
||||||
},
|
},
|
||||||
None => ()
|
None => ()
|
||||||
};
|
};
|
||||||
|
|
||||||
constellation_chan
|
constellation_chan
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Content process entry point.
|
||||||
|
pub fn run_content_process(token: String) {
|
||||||
|
let (unprivileged_content_sender, unprivileged_content_receiver) =
|
||||||
|
ipc::channel::<UnprivilegedPipelineContent>().unwrap();
|
||||||
|
let connection_bootstrap: IpcSender<IpcSender<UnprivilegedPipelineContent>> =
|
||||||
|
IpcSender::connect(token).unwrap();
|
||||||
|
connection_bootstrap.send(unprivileged_content_sender).unwrap();
|
||||||
|
|
||||||
|
let unprivileged_content = unprivileged_content_receiver.recv().unwrap();
|
||||||
|
opts::set_defaults(unprivileged_content.opts());
|
||||||
|
|
||||||
|
// Enter the sandbox if necessary.
|
||||||
|
if opts::get().sandbox {
|
||||||
|
ChildSandbox::new(sandboxing::content_process_sandbox_profile()).activate().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
script::init();
|
||||||
|
|
||||||
|
unprivileged_content.start_all::<layout::layout_task::LayoutTask,
|
||||||
|
script::script_task::ScriptTask>(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ use offscreen_gl_context::GLContext;
|
||||||
use servo::Browser;
|
use servo::Browser;
|
||||||
use servo::compositing::windowing::WindowEvent;
|
use servo::compositing::windowing::WindowEvent;
|
||||||
use servo::net_traits::hosts;
|
use servo::net_traits::hosts;
|
||||||
use servo::util::opts;
|
use servo::util::opts::{self, ArgumentParsingResult};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[cfg(not(target_os = "android"))]
|
#[cfg(not(target_os = "android"))]
|
||||||
|
@ -52,11 +52,17 @@ fn load_gl_when_headless() {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Parse the command line options and store them globally
|
// Parse the command line options and store them globally
|
||||||
opts::from_cmdline_args(&*args());
|
let opts_result = opts::from_cmdline_args(&*args());
|
||||||
|
|
||||||
if opts::get().is_running_problem_test && ::std::env::var("RUST_LOG").is_err() {
|
let content_process_token = if let ArgumentParsingResult::ContentProcess(token) = opts_result {
|
||||||
::std::env::set_var("RUST_LOG", "compositing::constellation");
|
Some(token)
|
||||||
}
|
} else {
|
||||||
|
if opts::get().is_running_problem_test && ::std::env::var("RUST_LOG").is_err() {
|
||||||
|
::std::env::set_var("RUST_LOG", "compositing::constellation");
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
env_logger::init().unwrap();
|
env_logger::init().unwrap();
|
||||||
|
|
||||||
|
@ -65,6 +71,10 @@ fn main() {
|
||||||
// Possibly interpret the `HOST_FILE` environment variable
|
// Possibly interpret the `HOST_FILE` environment variable
|
||||||
hosts::global_init();
|
hosts::global_init();
|
||||||
|
|
||||||
|
if let Some(token) = content_process_token {
|
||||||
|
return servo::run_content_process(token)
|
||||||
|
}
|
||||||
|
|
||||||
let window = if opts::get().headless {
|
let window = if opts::get().headless {
|
||||||
// Load gl functions even when in headless mode,
|
// Load gl functions even when in headless mode,
|
||||||
// to avoid crashing with webgl
|
// to avoid crashing with webgl
|
||||||
|
|
|
@ -2,18 +2,20 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use ipc_channel::ipc::{self, IpcSender};
|
use ipc_channel::ipc::{self, IpcSender, OpaqueIpcSender};
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
use opts;
|
use opts;
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
use std::any::Any;
|
use std::any::{Any, TypeId};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::marker::Reflect;
|
||||||
|
use std::mem;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering};
|
use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering};
|
||||||
use std::sync::mpsc::{self, Receiver, Sender};
|
use std::sync::mpsc::{self, Receiver, Sender};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref IN_PROCESS_SENDERS: Mutex<HashMap<usize, Box<Any + Send>>> =
|
static ref IN_PROCESS_SENDERS: Mutex<HashMap<usize, OpaqueSender>> =
|
||||||
Mutex::new(HashMap::new());
|
Mutex::new(HashMap::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +33,17 @@ impl<T> OptionalIpcSender<T> where T: Deserialize + Serialize + Send + Any {
|
||||||
OptionalIpcSender::InProcess(ref sender) => sender.send(value).map_err(|_| ()),
|
OptionalIpcSender::InProcess(ref sender) => sender.send(value).map_err(|_| ()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_opaque(self) -> OptionalOpaqueIpcSender {
|
||||||
|
match self {
|
||||||
|
OptionalIpcSender::OutOfProcess(ipc_sender) => {
|
||||||
|
OptionalOpaqueIpcSender::OutOfProcess(ipc_sender.to_opaque())
|
||||||
|
}
|
||||||
|
OptionalIpcSender::InProcess(sender) => {
|
||||||
|
OptionalOpaqueIpcSender::InProcess(OpaqueSender::new(sender))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Clone for OptionalIpcSender<T> where T: Deserialize + Serialize + Send + Any {
|
impl<T> Clone for OptionalIpcSender<T> where T: Deserialize + Serialize + Send + Any {
|
||||||
|
@ -49,18 +62,13 @@ impl<T> Clone for OptionalIpcSender<T> where T: Deserialize + Serialize + Send +
|
||||||
impl<T> Deserialize for OptionalIpcSender<T> where T: Deserialize + Serialize + Send + Any {
|
impl<T> Deserialize for OptionalIpcSender<T> where T: Deserialize + Serialize + Send + Any {
|
||||||
fn deserialize<D>(deserializer: &mut D)
|
fn deserialize<D>(deserializer: &mut D)
|
||||||
-> Result<OptionalIpcSender<T>, D::Error> where D: Deserializer {
|
-> Result<OptionalIpcSender<T>, D::Error> where D: Deserializer {
|
||||||
if opts::get().multiprocess {
|
if opts::multiprocess() {
|
||||||
return Ok(OptionalIpcSender::OutOfProcess(try!(Deserialize::deserialize(
|
return Ok(OptionalIpcSender::OutOfProcess(try!(Deserialize::deserialize(
|
||||||
deserializer))))
|
deserializer))))
|
||||||
}
|
}
|
||||||
let id: usize = try!(Deserialize::deserialize(deserializer));
|
let id: usize = try!(Deserialize::deserialize(deserializer));
|
||||||
let sender = (*IN_PROCESS_SENDERS.lock()
|
let sender = IN_PROCESS_SENDERS.lock().unwrap().remove(&id).unwrap();
|
||||||
.unwrap()
|
Ok(OptionalIpcSender::InProcess(sender.to().unwrap()))
|
||||||
.remove(&id)
|
|
||||||
.unwrap()
|
|
||||||
.downcast_ref::<Sender<T>>()
|
|
||||||
.unwrap()).clone();
|
|
||||||
Ok(OptionalIpcSender::InProcess(sender))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,16 +80,91 @@ impl<T> Serialize for OptionalIpcSender<T> where T: Deserialize + Serialize + Se
|
||||||
let id = NEXT_SENDER_ID.fetch_add(1, Ordering::SeqCst);
|
let id = NEXT_SENDER_ID.fetch_add(1, Ordering::SeqCst);
|
||||||
IN_PROCESS_SENDERS.lock()
|
IN_PROCESS_SENDERS.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.insert(id, Box::new((*sender).clone()) as Box<Any + Send>);
|
.insert(id, OpaqueSender::new((*sender).clone()));
|
||||||
id.serialize(serializer)
|
id.serialize(serializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum OptionalOpaqueIpcSender {
|
||||||
|
OutOfProcess(OpaqueIpcSender),
|
||||||
|
InProcess(OpaqueSender),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OptionalOpaqueIpcSender {
|
||||||
|
pub fn to<T>(self) -> OptionalIpcSender<T>
|
||||||
|
where T: Deserialize + Serialize + Send + Any + 'static {
|
||||||
|
match self {
|
||||||
|
OptionalOpaqueIpcSender::OutOfProcess(ipc_sender) => {
|
||||||
|
OptionalIpcSender::OutOfProcess(ipc_sender.to())
|
||||||
|
}
|
||||||
|
OptionalOpaqueIpcSender::InProcess(sender) => {
|
||||||
|
OptionalIpcSender::InProcess(sender.to().unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deserialize for OptionalOpaqueIpcSender {
|
||||||
|
fn deserialize<D>(deserializer: &mut D)
|
||||||
|
-> Result<OptionalOpaqueIpcSender, D::Error> where D: Deserializer {
|
||||||
|
if opts::multiprocess() {
|
||||||
|
return Ok(OptionalOpaqueIpcSender::OutOfProcess(try!(Deserialize::deserialize(
|
||||||
|
deserializer))))
|
||||||
|
}
|
||||||
|
let id: usize = try!(Deserialize::deserialize(deserializer));
|
||||||
|
let sender = IN_PROCESS_SENDERS.lock().unwrap().remove(&id).unwrap();
|
||||||
|
Ok(OptionalOpaqueIpcSender::InProcess(sender))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for OptionalOpaqueIpcSender {
|
||||||
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
|
||||||
|
match *self {
|
||||||
|
OptionalOpaqueIpcSender::OutOfProcess(ref ipc_sender) => {
|
||||||
|
ipc_sender.serialize(serializer)
|
||||||
|
}
|
||||||
|
OptionalOpaqueIpcSender::InProcess(ref sender) => {
|
||||||
|
let id = NEXT_SENDER_ID.fetch_add(1, Ordering::SeqCst);
|
||||||
|
IN_PROCESS_SENDERS.lock().unwrap().insert(id, (*sender).clone());
|
||||||
|
id.serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct OpaqueSender {
|
||||||
|
sender: Sender<()>,
|
||||||
|
id: TypeId,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OpaqueSender {
|
||||||
|
fn new<T>(sender: Sender<T>) -> OpaqueSender where T: 'static + Reflect + Send {
|
||||||
|
unsafe {
|
||||||
|
OpaqueSender {
|
||||||
|
sender: mem::transmute::<_, Sender<()>>(sender),
|
||||||
|
id: TypeId::of::<T>(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to<T>(self) -> Option<Sender<T>> where T: 'static + Reflect + Send {
|
||||||
|
unsafe {
|
||||||
|
if self.id != TypeId::of::<T>() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(mem::transmute::<_, Sender<T>>(self.sender))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn optional_ipc_channel<T>() -> (OptionalIpcSender<T>, Receiver<T>)
|
pub fn optional_ipc_channel<T>() -> (OptionalIpcSender<T>, Receiver<T>)
|
||||||
where T: Deserialize + Serialize + Send + Any {
|
where T: Deserialize + Serialize + Send + Any {
|
||||||
if opts::get().multiprocess {
|
if opts::multiprocess() {
|
||||||
let (ipc_sender, ipc_receiver) = ipc::channel().unwrap();
|
let (ipc_sender, ipc_receiver) = ipc::channel().unwrap();
|
||||||
let receiver = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_receiver);
|
let receiver = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_receiver);
|
||||||
(OptionalIpcSender::OutOfProcess(ipc_sender), receiver)
|
(OptionalIpcSender::OutOfProcess(ipc_sender), receiver)
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#![feature(optin_builtin_traits)]
|
#![feature(optin_builtin_traits)]
|
||||||
#![cfg_attr(not(target_os = "android"), feature(path_ext))]
|
#![cfg_attr(not(target_os = "android"), feature(path_ext))]
|
||||||
#![feature(plugin)]
|
#![feature(plugin)]
|
||||||
|
#![feature(reflect_marker)]
|
||||||
#![feature(slice_splits)]
|
#![feature(slice_splits)]
|
||||||
#![feature(step_by)]
|
#![feature(step_by)]
|
||||||
#![feature(step_trait)]
|
#![feature(step_trait)]
|
||||||
|
|
|
@ -18,10 +18,11 @@ use std::fs::File;
|
||||||
use std::io::{self, Read, Write};
|
use std::io::{self, Read, Write};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process;
|
use std::process;
|
||||||
|
use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
|
||||||
use url::{self, Url};
|
use url::{self, Url};
|
||||||
|
|
||||||
/// Global flags for Servo, currently set on the command line.
|
/// Global flags for Servo, currently set on the command line.
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
pub struct Opts {
|
pub struct Opts {
|
||||||
pub is_running_problem_test: bool,
|
pub is_running_problem_test: bool,
|
||||||
|
|
||||||
|
@ -143,9 +144,12 @@ pub struct Opts {
|
||||||
/// An optional string allowing the user agent to be set for testing.
|
/// An optional string allowing the user agent to be set for testing.
|
||||||
pub user_agent: String,
|
pub user_agent: String,
|
||||||
|
|
||||||
/// Whether to run in multiprocess mode.
|
/// Whether we're running in multiprocess mode.
|
||||||
pub multiprocess: bool,
|
pub multiprocess: bool,
|
||||||
|
|
||||||
|
/// Whether we're running inside the sandbox.
|
||||||
|
pub sandbox: bool,
|
||||||
|
|
||||||
/// Dumps the flow tree after a layout.
|
/// Dumps the flow tree after a layout.
|
||||||
pub dump_flow_tree: bool,
|
pub dump_flow_tree: bool,
|
||||||
|
|
||||||
|
@ -375,6 +379,13 @@ static FORCE_CPU_PAINTING: bool = true;
|
||||||
#[cfg(not(target_os = "android"))]
|
#[cfg(not(target_os = "android"))]
|
||||||
static FORCE_CPU_PAINTING: bool = false;
|
static FORCE_CPU_PAINTING: bool = false;
|
||||||
|
|
||||||
|
static MULTIPROCESS: AtomicBool = ATOMIC_BOOL_INIT;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn multiprocess() -> bool {
|
||||||
|
MULTIPROCESS.load(Ordering::Relaxed)
|
||||||
|
}
|
||||||
|
|
||||||
enum UserAgent {
|
enum UserAgent {
|
||||||
Desktop,
|
Desktop,
|
||||||
Android,
|
Android,
|
||||||
|
@ -460,6 +471,7 @@ pub fn default_opts() -> Opts {
|
||||||
initial_window_size: Size2D::typed(800, 600),
|
initial_window_size: Size2D::typed(800, 600),
|
||||||
user_agent: default_user_agent_string(DEFAULT_USER_AGENT),
|
user_agent: default_user_agent_string(DEFAULT_USER_AGENT),
|
||||||
multiprocess: false,
|
multiprocess: false,
|
||||||
|
sandbox: false,
|
||||||
dump_flow_tree: false,
|
dump_flow_tree: false,
|
||||||
dump_display_list: false,
|
dump_display_list: false,
|
||||||
dump_display_list_json: false,
|
dump_display_list_json: false,
|
||||||
|
@ -479,7 +491,7 @@ pub fn default_opts() -> Opts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_cmdline_args(args: &[String]) {
|
pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
|
||||||
let (app_name, args) = args.split_first().unwrap();
|
let (app_name, args) = args.split_first().unwrap();
|
||||||
|
|
||||||
let mut opts = Options::new();
|
let mut opts = Options::new();
|
||||||
|
@ -509,11 +521,14 @@ pub fn from_cmdline_args(args: &[String]) {
|
||||||
"Set custom user agent string (or android / gonk / desktop for platform default)",
|
"Set custom user agent string (or android / gonk / desktop for platform default)",
|
||||||
"NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)");
|
"NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)");
|
||||||
opts.optflag("M", "multiprocess", "Run in multiprocess mode");
|
opts.optflag("M", "multiprocess", "Run in multiprocess mode");
|
||||||
|
opts.optflag("S", "sandbox", "Run in a sandbox if multiprocess");
|
||||||
opts.optopt("Z", "debug",
|
opts.optopt("Z", "debug",
|
||||||
"A comma-separated string of debug options. Pass help to show available options.", "");
|
"A comma-separated string of debug options. Pass help to show available options.", "");
|
||||||
opts.optflag("h", "help", "Print this message");
|
opts.optflag("h", "help", "Print this message");
|
||||||
opts.optopt("", "resources-path", "Path to find static resources", "/home/servo/resources");
|
opts.optopt("", "resources-path", "Path to find static resources", "/home/servo/resources");
|
||||||
opts.optflag("", "sniff-mime-types" , "Enable MIME sniffing");
|
opts.optflag("", "sniff-mime-types" , "Enable MIME sniffing");
|
||||||
|
opts.optopt("", "content-process" , "Run as a content process and connect to the given pipe",
|
||||||
|
"servo-ipc-channel.abcdefg");
|
||||||
opts.optmulti("", "pref",
|
opts.optmulti("", "pref",
|
||||||
"A preference to set to enable", "dom.mozbrowser.enabled");
|
"A preference to set to enable", "dom.mozbrowser.enabled");
|
||||||
opts.optflag("b", "no-native-titlebar", "Do not use native titlebar");
|
opts.optflag("b", "no-native-titlebar", "Do not use native titlebar");
|
||||||
|
@ -530,6 +545,13 @@ pub fn from_cmdline_args(args: &[String]) {
|
||||||
process::exit(0);
|
process::exit(0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// If this is the content process, we'll receive the real options over IPC. So just fill in
|
||||||
|
// some dummy options for now.
|
||||||
|
if let Some(content_process) = opt_match.opt_str("content-process") {
|
||||||
|
MULTIPROCESS.store(true, Ordering::SeqCst);
|
||||||
|
return ArgumentParsingResult::ContentProcess(content_process);
|
||||||
|
}
|
||||||
|
|
||||||
let debug_string = match opt_match.opt_str("Z") {
|
let debug_string = match opt_match.opt_str("Z") {
|
||||||
Some(string) => string,
|
Some(string) => string,
|
||||||
None => String::new()
|
None => String::new()
|
||||||
|
@ -627,6 +649,10 @@ pub fn from_cmdline_args(args: &[String]) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if opt_match.opt_present("M") {
|
||||||
|
MULTIPROCESS.store(true, Ordering::SeqCst)
|
||||||
|
}
|
||||||
|
|
||||||
let user_agent = match opt_match.opt_str("u") {
|
let user_agent = match opt_match.opt_str("u") {
|
||||||
Some(ref ua) if ua == "android" => default_user_agent_string(UserAgent::Android),
|
Some(ref ua) if ua == "android" => default_user_agent_string(UserAgent::Android),
|
||||||
Some(ref ua) if ua == "gonk" => default_user_agent_string(UserAgent::Gonk),
|
Some(ref ua) if ua == "gonk" => default_user_agent_string(UserAgent::Gonk),
|
||||||
|
@ -675,6 +701,7 @@ pub fn from_cmdline_args(args: &[String]) {
|
||||||
initial_window_size: initial_window_size,
|
initial_window_size: initial_window_size,
|
||||||
user_agent: user_agent,
|
user_agent: user_agent,
|
||||||
multiprocess: opt_match.opt_present("M"),
|
multiprocess: opt_match.opt_present("M"),
|
||||||
|
sandbox: opt_match.opt_present("S"),
|
||||||
show_debug_borders: debug_options.show_compositor_borders,
|
show_debug_borders: debug_options.show_compositor_borders,
|
||||||
show_debug_fragment_borders: debug_options.show_fragment_borders,
|
show_debug_fragment_borders: debug_options.show_fragment_borders,
|
||||||
show_debug_parallel_paint: debug_options.show_parallel_paint,
|
show_debug_parallel_paint: debug_options.show_parallel_paint,
|
||||||
|
@ -704,6 +731,22 @@ pub fn from_cmdline_args(args: &[String]) {
|
||||||
for pref in opt_match.opt_strs("pref").iter() {
|
for pref in opt_match.opt_strs("pref").iter() {
|
||||||
prefs::set_pref(pref, PrefValue::Boolean(true));
|
prefs::set_pref(pref, PrefValue::Boolean(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArgumentParsingResult::ChromeProcess
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum ArgumentParsingResult {
|
||||||
|
ChromeProcess,
|
||||||
|
ContentProcess(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
static EXPERIMENTAL_ENABLED: AtomicBool = ATOMIC_BOOL_INIT;
|
||||||
|
|
||||||
|
/// Turn on experimental features globally. Normally this is done
|
||||||
|
/// during initialization by `set` or `from_cmdline_args`, but
|
||||||
|
/// tests that require experimental features will also set it.
|
||||||
|
pub fn set_experimental_enabled(new_value: bool) {
|
||||||
|
EXPERIMENTAL_ENABLED.store(new_value, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make Opts available globally. This saves having to clone and pass
|
// Make Opts available globally. This saves having to clone and pass
|
||||||
|
|
|
@ -558,7 +558,7 @@ pub fn parse_legacy_color(mut input: &str) -> Result<RGBA, ()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
#[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize, Serialize)]
|
||||||
pub struct LowercaseString {
|
pub struct LowercaseString {
|
||||||
inner: String,
|
inner: String,
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use ipc_channel::ipc::IpcSender;
|
||||||
|
use serde::Serialize;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
@ -15,15 +17,36 @@ pub fn spawn_named<F>(name: String, f: F)
|
||||||
builder.spawn(f).unwrap();
|
builder.spawn(f).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An abstraction over `Sender<T>` and `IpcSender<T>`, for use in
|
||||||
|
/// `spawn_named_with_send_on_failure`.
|
||||||
|
pub trait SendOnFailure {
|
||||||
|
type Value;
|
||||||
|
fn send_on_failure(&mut self, value: Self::Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> SendOnFailure for Sender<T> where T: Send + 'static {
|
||||||
|
type Value = T;
|
||||||
|
fn send_on_failure(&mut self, value: T) {
|
||||||
|
self.send(value).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> SendOnFailure for IpcSender<T> where T: Send + Serialize + 'static {
|
||||||
|
type Value = T;
|
||||||
|
fn send_on_failure(&mut self, value: T) {
|
||||||
|
self.send(value).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Arrange to send a particular message to a channel if the task fails.
|
/// Arrange to send a particular message to a channel if the task fails.
|
||||||
pub fn spawn_named_with_send_on_failure<F, T>(name: String,
|
pub fn spawn_named_with_send_on_failure<F, T, S>(name: String,
|
||||||
state: task_state::TaskState,
|
state: task_state::TaskState,
|
||||||
f: F,
|
f: F,
|
||||||
msg: T,
|
msg: T,
|
||||||
dest: Sender<T>)
|
mut dest: S)
|
||||||
where F: FnOnce() + Send + 'static,
|
where F: FnOnce() + Send + 'static,
|
||||||
T: Send + 'static
|
T: Send + 'static,
|
||||||
{
|
S: Send + SendOnFailure<Value=T> + 'static {
|
||||||
let future_handle = thread::Builder::new().name(name.to_owned()).spawn(move || {
|
let future_handle = thread::Builder::new().name(name.to_owned()).spawn(move || {
|
||||||
task_state::initialize(state);
|
task_state::initialize(state);
|
||||||
f()
|
f()
|
||||||
|
@ -35,8 +58,9 @@ pub fn spawn_named_with_send_on_failure<F, T>(name: String,
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(..) => {
|
Err(..) => {
|
||||||
debug!("{} failed, notifying constellation", name);
|
debug!("{} failed, notifying constellation", name);
|
||||||
dest.send(msg).unwrap();
|
dest.send_on_failure(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ use image::{DynamicImage, ImageFormat, RgbImage};
|
||||||
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||||
use keys::keycodes_to_keys;
|
use keys::keycodes_to_keys;
|
||||||
use msg::constellation_msg::CompositorMsg as ConstellationMsg;
|
use msg::constellation_msg::CompositorMsg as ConstellationMsg;
|
||||||
use msg::constellation_msg::{ConstellationChan, FrameId, LoadData, PipelineId};
|
use msg::constellation_msg::{FrameId, LoadData, PipelineId};
|
||||||
use msg::constellation_msg::{NavigationDirection, PixelFormat, WebDriverCommandMsg};
|
use msg::constellation_msg::{NavigationDirection, PixelFormat, WebDriverCommandMsg};
|
||||||
use msg::webdriver_msg::{LoadStatus, WebDriverFrameId, WebDriverJSError, WebDriverJSResult, WebDriverScriptCommand};
|
use msg::webdriver_msg::{LoadStatus, WebDriverFrameId, WebDriverJSError, WebDriverJSResult, WebDriverScriptCommand};
|
||||||
use regex::Captures;
|
use regex::Captures;
|
||||||
|
@ -37,6 +37,7 @@ use rustc_serialize::json::{Json, ToJson};
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
use std::sync::mpsc::Sender;
|
||||||
use std::thread::{self, sleep_ms};
|
use std::thread::{self, sleep_ms};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use util::prefs::{get_pref, reset_all_prefs, reset_pref, set_pref, PrefValue};
|
use util::prefs::{get_pref, reset_all_prefs, reset_pref, set_pref, PrefValue};
|
||||||
|
@ -57,7 +58,7 @@ fn extension_routes() -> Vec<(Method, &'static str, ServoExtensionRoute)> {
|
||||||
(Post, "/session/{sessionId}/servo/prefs/reset", ServoExtensionRoute::ResetPrefs)]
|
(Post, "/session/{sessionId}/servo/prefs/reset", ServoExtensionRoute::ResetPrefs)]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_server(port: u16, constellation_chan: ConstellationChan<ConstellationMsg>) {
|
pub fn start_server(port: u16, constellation_chan: Sender<ConstellationMsg>) {
|
||||||
let handler = Handler::new(constellation_chan);
|
let handler = Handler::new(constellation_chan);
|
||||||
spawn_named("WebdriverHttpServer".to_owned(), move || {
|
spawn_named("WebdriverHttpServer".to_owned(), move || {
|
||||||
server::start(SocketAddr::new("0.0.0.0".parse().unwrap(), port), handler,
|
server::start(SocketAddr::new("0.0.0.0".parse().unwrap(), port), handler,
|
||||||
|
@ -72,7 +73,7 @@ struct WebDriverSession {
|
||||||
|
|
||||||
struct Handler {
|
struct Handler {
|
||||||
session: Option<WebDriverSession>,
|
session: Option<WebDriverSession>,
|
||||||
constellation_chan: ConstellationChan<ConstellationMsg>,
|
constellation_chan: Sender<ConstellationMsg>,
|
||||||
script_timeout: u32,
|
script_timeout: u32,
|
||||||
load_timeout: u32,
|
load_timeout: u32,
|
||||||
implicit_wait_timeout: u32
|
implicit_wait_timeout: u32
|
||||||
|
@ -208,7 +209,7 @@ impl WebDriverSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Handler {
|
impl Handler {
|
||||||
pub fn new(constellation_chan: ConstellationChan<ConstellationMsg>) -> Handler {
|
pub fn new(constellation_chan: Sender<ConstellationMsg>) -> Handler {
|
||||||
Handler {
|
Handler {
|
||||||
session: None,
|
session: None,
|
||||||
constellation_chan: constellation_chan,
|
constellation_chan: constellation_chan,
|
||||||
|
@ -267,8 +268,7 @@ impl Handler {
|
||||||
|
|
||||||
fn pipeline(&self, frame_id: Option<FrameId>) -> Option<PipelineId> {
|
fn pipeline(&self, frame_id: Option<FrameId>) -> Option<PipelineId> {
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
let ConstellationChan(ref const_chan) = self.constellation_chan;
|
self.constellation_chan.send(ConstellationMsg::GetPipeline(frame_id, sender)).unwrap();
|
||||||
const_chan.send(ConstellationMsg::GetPipeline(frame_id, sender)).unwrap();
|
|
||||||
|
|
||||||
|
|
||||||
receiver.recv().unwrap()
|
receiver.recv().unwrap()
|
||||||
|
@ -307,9 +307,8 @@ impl Handler {
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
|
|
||||||
let load_data = LoadData::new(url);
|
let load_data = LoadData::new(url);
|
||||||
let ConstellationChan(ref const_chan) = self.constellation_chan;
|
|
||||||
let cmd_msg = WebDriverCommandMsg::LoadUrl(pipeline_id, load_data, sender.clone());
|
let cmd_msg = WebDriverCommandMsg::LoadUrl(pipeline_id, load_data, sender.clone());
|
||||||
const_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
||||||
|
|
||||||
self.wait_for_load(sender, receiver)
|
self.wait_for_load(sender, receiver)
|
||||||
}
|
}
|
||||||
|
@ -337,10 +336,9 @@ impl Handler {
|
||||||
|
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
|
|
||||||
let ConstellationChan(ref const_chan) = self.constellation_chan;
|
|
||||||
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id,
|
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id,
|
||||||
WebDriverScriptCommand::GetUrl(sender));
|
WebDriverScriptCommand::GetUrl(sender));
|
||||||
const_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
||||||
|
|
||||||
let url = receiver.recv().unwrap();
|
let url = receiver.recv().unwrap();
|
||||||
|
|
||||||
|
@ -348,14 +346,12 @@ impl Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_go_back(&self) -> WebDriverResult<WebDriverResponse> {
|
fn handle_go_back(&self) -> WebDriverResult<WebDriverResponse> {
|
||||||
let ConstellationChan(ref const_chan) = self.constellation_chan;
|
self.constellation_chan.send(ConstellationMsg::Navigate(None, NavigationDirection::Back)).unwrap();
|
||||||
const_chan.send(ConstellationMsg::Navigate(None, NavigationDirection::Back)).unwrap();
|
|
||||||
Ok(WebDriverResponse::Void)
|
Ok(WebDriverResponse::Void)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_go_forward(&self) -> WebDriverResult<WebDriverResponse> {
|
fn handle_go_forward(&self) -> WebDriverResult<WebDriverResponse> {
|
||||||
let ConstellationChan(ref const_chan) = self.constellation_chan;
|
self.constellation_chan.send(ConstellationMsg::Navigate(None, NavigationDirection::Forward)).unwrap();
|
||||||
const_chan.send(ConstellationMsg::Navigate(None, NavigationDirection::Forward)).unwrap();
|
|
||||||
Ok(WebDriverResponse::Void)
|
Ok(WebDriverResponse::Void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,9 +360,8 @@ impl Handler {
|
||||||
|
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
|
|
||||||
let ConstellationChan(ref const_chan) = self.constellation_chan;
|
|
||||||
let cmd_msg = WebDriverCommandMsg::Refresh(pipeline_id, sender.clone());
|
let cmd_msg = WebDriverCommandMsg::Refresh(pipeline_id, sender.clone());
|
||||||
const_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
||||||
|
|
||||||
self.wait_for_load(sender, receiver)
|
self.wait_for_load(sender, receiver)
|
||||||
}
|
}
|
||||||
|
@ -375,10 +370,9 @@ impl Handler {
|
||||||
let pipeline_id = try!(self.root_pipeline());
|
let pipeline_id = try!(self.root_pipeline());
|
||||||
|
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
let ConstellationChan(ref const_chan) = self.constellation_chan;
|
|
||||||
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id,
|
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id,
|
||||||
WebDriverScriptCommand::GetTitle(sender));
|
WebDriverScriptCommand::GetTitle(sender));
|
||||||
const_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
||||||
let value = receiver.recv().unwrap();
|
let value = receiver.recv().unwrap();
|
||||||
Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json())))
|
Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json())))
|
||||||
}
|
}
|
||||||
|
@ -406,10 +400,9 @@ impl Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
let ConstellationChan(ref const_chan) = self.constellation_chan;
|
|
||||||
let cmd = WebDriverScriptCommand::FindElementCSS(parameters.value.clone(), sender);
|
let cmd = WebDriverScriptCommand::FindElementCSS(parameters.value.clone(), sender);
|
||||||
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd);
|
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd);
|
||||||
const_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
||||||
match receiver.recv().unwrap() {
|
match receiver.recv().unwrap() {
|
||||||
Ok(value) => {
|
Ok(value) => {
|
||||||
let value_resp = value.map(|x| WebElement::new(x).to_json()).to_json();
|
let value_resp = value.map(|x| WebElement::new(x).to_json()).to_json();
|
||||||
|
@ -448,16 +441,14 @@ impl Handler {
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
let cmd = WebDriverScriptCommand::GetFrameId(frame_id, sender);
|
let cmd = WebDriverScriptCommand::GetFrameId(frame_id, sender);
|
||||||
{
|
{
|
||||||
let ConstellationChan(ref const_chan) = self.constellation_chan;
|
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(
|
||||||
const_chan.send(ConstellationMsg::WebDriverCommand(
|
|
||||||
WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd))).unwrap();
|
WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd))).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let frame = match receiver.recv().unwrap() {
|
let frame = match receiver.recv().unwrap() {
|
||||||
Ok(Some(pipeline_id)) => {
|
Ok(Some(pipeline_id)) => {
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
let ConstellationChan(ref const_chan) = self.constellation_chan;
|
self.constellation_chan.send(ConstellationMsg::GetFrame(pipeline_id, sender)).unwrap();
|
||||||
const_chan.send(ConstellationMsg::GetFrame(pipeline_id, sender)).unwrap();
|
|
||||||
receiver.recv().unwrap()
|
receiver.recv().unwrap()
|
||||||
},
|
},
|
||||||
Ok(None) => None,
|
Ok(None) => None,
|
||||||
|
@ -481,10 +472,9 @@ impl Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
let ConstellationChan(ref const_chan) = self.constellation_chan;
|
|
||||||
let cmd = WebDriverScriptCommand::FindElementsCSS(parameters.value.clone(), sender);
|
let cmd = WebDriverScriptCommand::FindElementsCSS(parameters.value.clone(), sender);
|
||||||
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd);
|
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd);
|
||||||
const_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
||||||
match receiver.recv().unwrap() {
|
match receiver.recv().unwrap() {
|
||||||
Ok(value) => {
|
Ok(value) => {
|
||||||
let resp_value: Vec<Json> = value.into_iter().map(
|
let resp_value: Vec<Json> = value.into_iter().map(
|
||||||
|
@ -500,10 +490,9 @@ impl Handler {
|
||||||
let pipeline_id = try!(self.frame_pipeline());
|
let pipeline_id = try!(self.frame_pipeline());
|
||||||
|
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
let ConstellationChan(ref const_chan) = self.constellation_chan;
|
|
||||||
let cmd = WebDriverScriptCommand::GetElementText(element.id.clone(), sender);
|
let cmd = WebDriverScriptCommand::GetElementText(element.id.clone(), sender);
|
||||||
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd);
|
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd);
|
||||||
const_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
||||||
match receiver.recv().unwrap() {
|
match receiver.recv().unwrap() {
|
||||||
Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json()))),
|
Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json()))),
|
||||||
Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference,
|
Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference,
|
||||||
|
@ -515,10 +504,9 @@ impl Handler {
|
||||||
let pipeline_id = try!(self.frame_pipeline());
|
let pipeline_id = try!(self.frame_pipeline());
|
||||||
|
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
let ConstellationChan(ref const_chan) = self.constellation_chan;
|
|
||||||
let cmd = WebDriverScriptCommand::GetActiveElement(sender);
|
let cmd = WebDriverScriptCommand::GetActiveElement(sender);
|
||||||
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd);
|
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd);
|
||||||
const_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
||||||
let value = receiver.recv().unwrap().map(|x| WebElement::new(x).to_json());
|
let value = receiver.recv().unwrap().map(|x| WebElement::new(x).to_json());
|
||||||
Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json())))
|
Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json())))
|
||||||
}
|
}
|
||||||
|
@ -527,10 +515,9 @@ impl Handler {
|
||||||
let pipeline_id = try!(self.frame_pipeline());
|
let pipeline_id = try!(self.frame_pipeline());
|
||||||
|
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
let ConstellationChan(ref const_chan) = self.constellation_chan;
|
|
||||||
let cmd = WebDriverScriptCommand::GetElementTagName(element.id.clone(), sender);
|
let cmd = WebDriverScriptCommand::GetElementTagName(element.id.clone(), sender);
|
||||||
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd);
|
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd);
|
||||||
const_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
||||||
match receiver.recv().unwrap() {
|
match receiver.recv().unwrap() {
|
||||||
Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json()))),
|
Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json()))),
|
||||||
Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference,
|
Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference,
|
||||||
|
@ -542,10 +529,9 @@ impl Handler {
|
||||||
let pipeline_id = try!(self.frame_pipeline());
|
let pipeline_id = try!(self.frame_pipeline());
|
||||||
|
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
let ConstellationChan(ref const_chan) = self.constellation_chan;
|
|
||||||
let cmd = WebDriverScriptCommand::GetElementAttribute(element.id.clone(), name.clone(), sender);
|
let cmd = WebDriverScriptCommand::GetElementAttribute(element.id.clone(), name.clone(), sender);
|
||||||
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd);
|
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd);
|
||||||
const_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
||||||
match receiver.recv().unwrap() {
|
match receiver.recv().unwrap() {
|
||||||
Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json()))),
|
Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json()))),
|
||||||
Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference,
|
Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference,
|
||||||
|
@ -601,9 +587,8 @@ impl Handler {
|
||||||
-> WebDriverResult<WebDriverResponse> {
|
-> WebDriverResult<WebDriverResponse> {
|
||||||
let pipeline_id = try!(self.frame_pipeline());
|
let pipeline_id = try!(self.frame_pipeline());
|
||||||
|
|
||||||
let ConstellationChan(ref const_chan) = self.constellation_chan;
|
|
||||||
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id, command);
|
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id, command);
|
||||||
const_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
||||||
|
|
||||||
match receiver.recv().unwrap() {
|
match receiver.recv().unwrap() {
|
||||||
Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json()))),
|
Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json()))),
|
||||||
|
@ -618,12 +603,11 @@ impl Handler {
|
||||||
keys: &SendKeysParameters) -> WebDriverResult<WebDriverResponse> {
|
keys: &SendKeysParameters) -> WebDriverResult<WebDriverResponse> {
|
||||||
let pipeline_id = try!(self.frame_pipeline());
|
let pipeline_id = try!(self.frame_pipeline());
|
||||||
|
|
||||||
let ConstellationChan(ref const_chan) = self.constellation_chan;
|
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
|
|
||||||
let cmd = WebDriverScriptCommand::FocusElement(element.id.clone(), sender);
|
let cmd = WebDriverScriptCommand::FocusElement(element.id.clone(), sender);
|
||||||
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd);
|
let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd);
|
||||||
const_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
||||||
|
|
||||||
// TODO: distinguish the not found and not focusable cases
|
// TODO: distinguish the not found and not focusable cases
|
||||||
try!(receiver.recv().unwrap().or_else(|_| Err(WebDriverError::new(
|
try!(receiver.recv().unwrap().or_else(|_| Err(WebDriverError::new(
|
||||||
|
@ -633,7 +617,7 @@ impl Handler {
|
||||||
Err(WebDriverError::new(ErrorStatus::UnsupportedOperation, "Failed to convert keycodes"))));
|
Err(WebDriverError::new(ErrorStatus::UnsupportedOperation, "Failed to convert keycodes"))));
|
||||||
|
|
||||||
let cmd_msg = WebDriverCommandMsg::SendKeys(pipeline_id, keys);
|
let cmd_msg = WebDriverCommandMsg::SendKeys(pipeline_id, keys);
|
||||||
const_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
||||||
|
|
||||||
Ok(WebDriverResponse::Void)
|
Ok(WebDriverResponse::Void)
|
||||||
}
|
}
|
||||||
|
@ -647,9 +631,8 @@ impl Handler {
|
||||||
|
|
||||||
for _ in 0..iterations {
|
for _ in 0..iterations {
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
let ConstellationChan(ref const_chan) = self.constellation_chan;
|
|
||||||
let cmd_msg = WebDriverCommandMsg::TakeScreenshot(pipeline_id, sender);
|
let cmd_msg = WebDriverCommandMsg::TakeScreenshot(pipeline_id, sender);
|
||||||
const_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
||||||
|
|
||||||
if let Some(x) = receiver.recv().unwrap() {
|
if let Some(x) = receiver.recv().unwrap() {
|
||||||
img = Some(x);
|
img = Some(x);
|
||||||
|
|
16
ports/cef/Cargo.lock
generated
16
ports/cef/Cargo.lock
generated
|
@ -253,6 +253,7 @@ dependencies = [
|
||||||
"core-text 0.1.0 (git+https://github.com/servo/core-text-rs)",
|
"core-text 0.1.0 (git+https://github.com/servo/core-text-rs)",
|
||||||
"devtools_traits 0.0.1",
|
"devtools_traits 0.0.1",
|
||||||
"euclid 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gaol 0.0.1 (git+https://github.com/pcwalton/gaol)",
|
||||||
"gfx 0.0.1",
|
"gfx 0.0.1",
|
||||||
"gfx_traits 0.0.1",
|
"gfx_traits 0.0.1",
|
||||||
"gleam 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gleam 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -260,6 +261,7 @@ dependencies = [
|
||||||
"ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)",
|
"ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)",
|
||||||
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
|
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
|
||||||
"layout_traits 0.0.1",
|
"layout_traits 0.0.1",
|
||||||
|
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"msg 0.0.1",
|
"msg 0.0.1",
|
||||||
"net_traits 0.0.1",
|
"net_traits 0.0.1",
|
||||||
|
@ -268,6 +270,8 @@ dependencies = [
|
||||||
"plugins 0.0.1",
|
"plugins 0.0.1",
|
||||||
"profile_traits 0.0.1",
|
"profile_traits 0.0.1",
|
||||||
"script_traits 0.0.1",
|
"script_traits 0.0.1",
|
||||||
|
"serde 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde_macros 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"style_traits 0.0.1",
|
"style_traits 0.0.1",
|
||||||
"time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -559,6 +563,16 @@ dependencies = [
|
||||||
"mac 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mac 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gaol"
|
||||||
|
version = "0.0.1"
|
||||||
|
source = "git+https://github.com/pcwalton/gaol#71865ff8a1824cbc1cbee4d388d56c5ba1b5ffc2"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gcc"
|
name = "gcc"
|
||||||
version = "0.3.16"
|
version = "0.3.16"
|
||||||
|
@ -1555,9 +1569,11 @@ dependencies = [
|
||||||
"devtools_traits 0.0.1",
|
"devtools_traits 0.0.1",
|
||||||
"env_logger 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gaol 0.0.1 (git+https://github.com/pcwalton/gaol)",
|
||||||
"gfx 0.0.1",
|
"gfx 0.0.1",
|
||||||
"gleam 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gleam 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glutin_app 0.0.1",
|
"glutin_app 0.0.1",
|
||||||
|
"ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)",
|
||||||
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
|
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
|
||||||
"layout 0.0.1",
|
"layout 0.0.1",
|
||||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
16
ports/gonk/Cargo.lock
generated
16
ports/gonk/Cargo.lock
generated
|
@ -245,6 +245,7 @@ dependencies = [
|
||||||
"core-text 0.1.0 (git+https://github.com/servo/core-text-rs)",
|
"core-text 0.1.0 (git+https://github.com/servo/core-text-rs)",
|
||||||
"devtools_traits 0.0.1",
|
"devtools_traits 0.0.1",
|
||||||
"euclid 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gaol 0.0.1 (git+https://github.com/pcwalton/gaol)",
|
||||||
"gfx 0.0.1",
|
"gfx 0.0.1",
|
||||||
"gfx_traits 0.0.1",
|
"gfx_traits 0.0.1",
|
||||||
"gleam 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gleam 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -252,6 +253,7 @@ dependencies = [
|
||||||
"ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)",
|
"ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)",
|
||||||
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
|
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
|
||||||
"layout_traits 0.0.1",
|
"layout_traits 0.0.1",
|
||||||
|
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"msg 0.0.1",
|
"msg 0.0.1",
|
||||||
"net_traits 0.0.1",
|
"net_traits 0.0.1",
|
||||||
|
@ -260,6 +262,8 @@ dependencies = [
|
||||||
"plugins 0.0.1",
|
"plugins 0.0.1",
|
||||||
"profile_traits 0.0.1",
|
"profile_traits 0.0.1",
|
||||||
"script_traits 0.0.1",
|
"script_traits 0.0.1",
|
||||||
|
"serde 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde_macros 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"style_traits 0.0.1",
|
"style_traits 0.0.1",
|
||||||
"time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -561,6 +565,16 @@ dependencies = [
|
||||||
"mac 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mac 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gaol"
|
||||||
|
version = "0.0.1"
|
||||||
|
source = "git+https://github.com/pcwalton/gaol#71865ff8a1824cbc1cbee4d388d56c5ba1b5ffc2"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gcc"
|
name = "gcc"
|
||||||
version = "0.3.16"
|
version = "0.3.16"
|
||||||
|
@ -1535,8 +1549,10 @@ dependencies = [
|
||||||
"devtools_traits 0.0.1",
|
"devtools_traits 0.0.1",
|
||||||
"env_logger 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gaol 0.0.1 (git+https://github.com/pcwalton/gaol)",
|
||||||
"gfx 0.0.1",
|
"gfx 0.0.1",
|
||||||
"gleam 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gleam 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)",
|
||||||
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
|
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
|
||||||
"layout 0.0.1",
|
"layout 0.0.1",
|
||||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue