diff options
-rw-r--r-- | components/constellation/constellation.rs | 13 | ||||
-rw-r--r-- | components/constellation/pipeline.rs | 12 | ||||
-rw-r--r-- | components/layout/layout_thread.rs | 13 | ||||
-rw-r--r-- | components/layout_traits/lib.rs | 6 | ||||
-rw-r--r-- | components/script/layout_interface.rs | 30 | ||||
-rw-r--r-- | components/script/script_thread.rs | 30 | ||||
-rw-r--r-- | components/script_traits/lib.rs | 15 | ||||
-rw-r--r-- | components/servo/lib.rs | 6 |
8 files changed, 47 insertions, 78 deletions
diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index f595b4f6573..4a3bb4ce2b3 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -89,7 +89,7 @@ enum ReadyToSave { /// `ScriptThreadFactory` (which in practice are implemented by /// `LayoutThread` in the `layout` crate, and `ScriptThread` in /// the `script` crate). -pub struct Constellation<LTF, STF> { +pub struct Constellation<Message, LTF, STF> { /// A channel through which script messages can be sent to this object. script_sender: IpcSender<FromScriptMsg>, @@ -166,7 +166,7 @@ pub struct Constellation<LTF, STF> { /// A channel through which messages can be sent to the memory profiler. mem_profiler_chan: mem::ProfilerChan, - phantom: PhantomData<(LTF, STF)>, + phantom: PhantomData<(Message, LTF, STF)>, window_size: WindowSizeData, @@ -318,7 +318,10 @@ enum ChildProcess { Unsandboxed(process::Child), } -impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF> { +impl<Message, LTF, STF> Constellation<Message, LTF, STF> + where LTF: LayoutThreadFactory<Message=Message>, + STF: ScriptThreadFactory<Message=Message> +{ pub fn start(state: InitialConstellationState) -> Sender<FromCompositorMsg> { let (ipc_script_sender, ipc_script_receiver) = ipc::channel().expect("ipc channel failure"); let script_receiver = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_script_receiver); @@ -333,7 +336,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF> let compositor_sender_clone = compositor_sender.clone(); spawn_named("Constellation".to_owned(), move || { - let mut constellation: Constellation<LTF, STF> = Constellation { + let mut constellation: Constellation<Message, LTF, STF> = Constellation { script_sender: ipc_script_sender, compositor_sender: compositor_sender_clone, layout_sender: ipc_layout_sender, @@ -455,7 +458,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF> if opts::multiprocess() { self.spawn_multiprocess(pipeline_id, unprivileged_pipeline_content); } else { - unprivileged_pipeline_content.start_all::<LTF, STF>(false); + unprivileged_pipeline_content.start_all::<Message, LTF, STF>(false); } } diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs index 8f9252bd263..67c17c1028d 100644 --- a/components/constellation/pipeline.rs +++ b/components/constellation/pipeline.rs @@ -409,13 +409,11 @@ pub struct UnprivilegedPipelineContent { } impl UnprivilegedPipelineContent { - pub fn start_all<LTF, STF>(mut self, wait_for_completion: bool) - where LTF: LayoutThreadFactory, - STF: ScriptThreadFactory + pub fn start_all<Message, LTF, STF>(mut self, wait_for_completion: bool) + where LTF: LayoutThreadFactory<Message=Message>, + STF: ScriptThreadFactory<Message=Message> { - let layout_pair = STF::create_layout_channel(); - - STF::create(InitialScriptState { + let layout_pair = STF::create(InitialScriptState { id: self.id, parent_info: self.parent_info, compositor: self.script_to_compositor_chan, @@ -434,7 +432,7 @@ impl UnprivilegedPipelineContent { window_size: self.window_size, pipeline_namespace_id: self.pipeline_namespace_id, content_process_shutdown_chan: self.script_content_process_shutdown_chan.clone(), - }, &layout_pair, self.load_data.clone()); + }, self.load_data.clone()); LTF::create(self.id, self.load_data.url.clone(), diff --git a/components/layout/layout_thread.rs b/components/layout/layout_thread.rs index cbff9d2b7bd..5472b9c20c4 100644 --- a/components/layout/layout_thread.rs +++ b/components/layout/layout_thread.rs @@ -50,11 +50,10 @@ use query::{process_node_overflow_request, process_resolved_style_request, proce use query::{process_offset_parent_query}; use script::dom::node::OpaqueStyleAndLayoutData; use script::layout_interface::{LayoutRPC, OffsetParentResponse, NodeOverflowResponse, MarginStyleResponse}; -use script::layout_interface::{Msg, NewLayoutThreadInfo, Reflow, ReflowQueryType}; -use script::layout_interface::{ScriptLayoutChan, ScriptReflow}; +use script::layout_interface::{Msg, NewLayoutThreadInfo, Reflow, ReflowQueryType, ScriptReflow}; use script::reporter::CSSErrorReporter; use script_traits::ConstellationControlMsg; -use script_traits::{LayoutControlMsg, LayoutMsg as ConstellationMsg, OpaqueScriptLayoutChannel}; +use script_traits::{LayoutControlMsg, LayoutMsg as ConstellationMsg}; use sequential; use serde_json; use std::borrow::ToOwned; @@ -246,11 +245,13 @@ pub struct LayoutThread { } impl LayoutThreadFactory for LayoutThread { + type Message = Msg; + /// Spawns a new layout thread. fn create(id: PipelineId, url: Url, is_iframe: bool, - chan: OpaqueScriptLayoutChannel, + chan: (Sender<Msg>, Receiver<Msg>), pipeline_port: IpcReceiver<LayoutControlMsg>, constellation_chan: IpcSender<ConstellationMsg>, panic_chan: IpcSender<PanicMsg>, @@ -267,11 +268,11 @@ impl LayoutThreadFactory for LayoutThread { thread_state::LAYOUT, move || { { // Ensures layout thread is destroyed before we send shutdown message - let sender = chan.sender(); + let sender = chan.0; let layout = LayoutThread::new(id, url, is_iframe, - chan.receiver(), + chan.1, pipeline_port, constellation_chan, script_chan, diff --git a/components/layout_traits/lib.rs b/components/layout_traits/lib.rs index 5466900b7bf..b6a93e98a25 100644 --- a/components/layout_traits/lib.rs +++ b/components/layout_traits/lib.rs @@ -30,7 +30,8 @@ use msg::constellation_msg::{PanicMsg, PipelineId, PipelineNamespaceId, Pipeline use net_traits::image_cache_thread::ImageCacheThread; use profile_traits::{mem, time}; use script_traits::LayoutMsg as ConstellationMsg; -use script_traits::{LayoutControlMsg, ConstellationControlMsg, OpaqueScriptLayoutChannel}; +use script_traits::{LayoutControlMsg, ConstellationControlMsg}; +use std::sync::mpsc::{Sender, Receiver}; use url::Url; use util::ipc::OptionalIpcSender; @@ -41,10 +42,11 @@ pub struct LayoutControlChan(pub IpcSender<LayoutControlMsg>); // A static method creating a layout thread // Here to remove the compositor -> layout dependency pub trait LayoutThreadFactory { + type Message; fn create(id: PipelineId, url: Url, is_iframe: bool, - chan: OpaqueScriptLayoutChannel, + chan: (Sender<Self::Message>, Receiver<Self::Message>), pipeline_port: IpcReceiver<LayoutControlMsg>, constellation_chan: IpcSender<ConstellationMsg>, panic_chan: IpcSender<PanicMsg>, diff --git a/components/script/layout_interface.rs b/components/script/layout_interface.rs index 2a6e0b1d79a..a97bab045a0 100644 --- a/components/script/layout_interface.rs +++ b/components/script/layout_interface.rs @@ -16,8 +16,7 @@ use msg::constellation_msg::{PanicMsg, PipelineId, WindowSizeData}; use net_traits::image_cache_thread::ImageCacheThread; use profile_traits::mem::ReportsChan; use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg}; -use script_traits::{OpaqueScriptLayoutChannel, UntrustedNodeAddress}; -use std::any::Any; +use script_traits::{UntrustedNodeAddress}; use std::sync::Arc; use std::sync::mpsc::{Receiver, Sender, channel}; use string_cache::Atom; @@ -230,36 +229,11 @@ impl LayoutChan { } } -/// A trait to manage opaque references to script<->layout channels without needing -/// to expose the message type to crates that don't need to know about them. -pub trait ScriptLayoutChan { - fn new(sender: Sender<Msg>, receiver: Receiver<Msg>) -> Self; - fn sender(&self) -> Sender<Msg>; - fn receiver(self) -> Receiver<Msg>; -} - -impl ScriptLayoutChan for OpaqueScriptLayoutChannel { - fn new(sender: Sender<Msg>, receiver: Receiver<Msg>) -> OpaqueScriptLayoutChannel { - let inner = (box sender as Box<Any + Send>, box receiver as Box<Any + Send>); - OpaqueScriptLayoutChannel(inner) - } - - fn sender(&self) -> Sender<Msg> { - let &OpaqueScriptLayoutChannel((ref sender, _)) = self; - (*sender.downcast_ref::<Sender<Msg>>().unwrap()).clone() - } - - fn receiver(self) -> Receiver<Msg> { - let OpaqueScriptLayoutChannel((_, receiver)) = self; - *receiver.downcast::<Receiver<Msg>>().unwrap() - } -} - pub struct NewLayoutThreadInfo { pub id: PipelineId, pub url: Url, pub is_parent: bool, - pub layout_pair: OpaqueScriptLayoutChannel, + pub layout_pair: (Sender<Msg>, Receiver<Msg>), pub pipeline_port: IpcReceiver<LayoutControlMsg>, pub constellation_chan: IpcSender<ConstellationMsg>, pub panic_chan: IpcSender<PanicMsg>, diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 330eebafdfe..ac640b3e7d0 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -58,7 +58,7 @@ use js::jsapi::{JSContext, JS_SetWrapObjectCallbacks, JSTracer, SetWindowProxyCl use js::jsval::UndefinedValue; use js::rust::Runtime; use layout_interface::{ReflowQueryType}; -use layout_interface::{self, LayoutChan, NewLayoutThreadInfo, ScriptLayoutChan}; +use layout_interface::{self, LayoutChan, NewLayoutThreadInfo}; use mem::heap_size_of_self_and_children; use msg::constellation_msg::{LoadData, PanicMsg, PipelineId, PipelineNamespace}; use msg::constellation_msg::{SubpageId, WindowSizeData, WindowSizeType}; @@ -80,10 +80,9 @@ use script_traits::CompositorEvent::{KeyEvent, MouseButtonEvent, MouseMoveEvent, use script_traits::CompositorEvent::{TouchEvent, TouchpadPressureEvent}; use script_traits::{CompositorEvent, ConstellationControlMsg, EventResult}; use script_traits::{InitialScriptState, MouseButton, MouseEventType, MozBrowserEvent, NewLayoutInfo}; -use script_traits::{LayoutMsg, OpaqueScriptLayoutChannel, ScriptMsg as ConstellationMsg}; +use script_traits::{LayoutMsg, ScriptMsg as ConstellationMsg}; use script_traits::{ScriptThreadFactory, ScriptToCompositorMsg, TimerEvent, TimerEventRequest, TimerSource}; use script_traits::{TouchEventType, TouchId}; -use std::any::Any; use std::borrow::ToOwned; use std::cell::{Cell, RefCell}; use std::collections::HashSet; @@ -428,22 +427,16 @@ impl<'a> Drop for ScriptMemoryFailsafe<'a> { } impl ScriptThreadFactory for ScriptThread { - fn create_layout_channel() -> OpaqueScriptLayoutChannel { - let (chan, port) = channel(); - ScriptLayoutChan::new(chan, port) - } - - fn clone_layout_channel(pair: &OpaqueScriptLayoutChannel) - -> Box<Any + Send> { - box pair.sender() as Box<Any + Send> - } + type Message = layout_interface::Msg; fn create(state: InitialScriptState, - layout_chan: &OpaqueScriptLayoutChannel, - load_data: LoadData) { + load_data: LoadData) + -> (Sender<layout_interface::Msg>, Receiver<layout_interface::Msg>) { let panic_chan = state.panic_chan.clone(); let (script_chan, script_port) = channel(); - let layout_chan = LayoutChan(layout_chan.sender()); + + let (sender, receiver) = channel(); + let layout_chan = LayoutChan(sender.clone()); let pipeline_id = state.id; thread::spawn_named_with_send_on_panic(format!("ScriptThread {:?}", state.id), thread_state::SCRIPT, @@ -479,6 +472,8 @@ impl ScriptThreadFactory for ScriptThread { // This must always be the very last operation performed before the thread completes failsafe.neuter(); }, Some(pipeline_id), panic_chan); + + (sender, receiver) } } @@ -1103,9 +1098,8 @@ impl ScriptThread { content_process_shutdown_chan, } = new_layout_info; - let layout_pair = ScriptThread::create_layout_channel(); - let layout_chan = LayoutChan(*ScriptThread::clone_layout_channel( - &layout_pair).downcast::<Sender<layout_interface::Msg>>().unwrap()); + let layout_pair = channel(); + let layout_chan = LayoutChan(layout_pair.0.clone()); let layout_creation_info = NewLayoutThreadInfo { id: new_pipeline_id, diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index 8d39895ed46..7ee96092aba 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -53,6 +53,7 @@ use net_traits::response::HttpsState; use profile_traits::mem; use std::any::Any; use std::collections::HashMap; +use std::sync::mpsc::{Sender, Receiver}; use url::Url; use util::ipc::OptionalOpaqueIpcSender; @@ -246,10 +247,6 @@ pub enum TouchpadPressurePhase { AfterSecondClick, } -/// An opaque wrapper around script<->layout channels to avoid leaking message types into -/// crates that don't need to know about them. -pub struct OpaqueScriptLayoutChannel(pub (Box<Any + Send>, Box<Any + Send>)); - /// Requests a TimerEvent-Message be sent after the given duration. #[derive(Deserialize, Serialize)] pub struct TimerEventRequest(pub IpcSender<TimerEvent>, @@ -344,14 +341,12 @@ pub struct InitialScriptState { /// This trait allows creating a `ScriptThread` without depending on the `script` /// crate. pub trait ScriptThreadFactory { + /// Type of message sent from script to layout. + type Message; /// Create a `ScriptThread`. fn create(state: InitialScriptState, - layout_chan: &OpaqueScriptLayoutChannel, - load_data: LoadData); - /// Create a script -> layout channel (`Sender`, `Receiver` pair). - fn create_layout_channel() -> OpaqueScriptLayoutChannel; - /// Clone the `Sender` in `pair`. - fn clone_layout_channel(pair: &OpaqueScriptLayoutChannel) -> Box<Any + Send>; + load_data: LoadData) + -> (Sender<Self::Message>, Receiver<Self::Message>); } /// Messages sent from the script thread to the compositor diff --git a/components/servo/lib.rs b/components/servo/lib.rs index e208a4e89f1..71a3bc77309 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -231,7 +231,8 @@ fn create_constellation(opts: opts::Opts, webrender_api_sender: webrender_api_sender, }; let constellation_chan = - Constellation::<layout::layout_thread::LayoutThread, + Constellation::<script::layout_interface::Msg, + layout::layout_thread::LayoutThread, script::script_thread::ScriptThread>::start(initial_state); // Send the URL command to the constellation. @@ -264,7 +265,8 @@ pub fn run_content_process(token: String) { script::init(); - unprivileged_content.start_all::<layout::layout_thread::LayoutThread, + unprivileged_content.start_all::<script::layout_interface::Msg, + layout::layout_thread::LayoutThread, script::script_thread::ScriptThread>(true); } |