diff options
author | Gregory Terzian <gterzian@users.noreply.github.com> | 2019-08-19 21:57:12 +0200 |
---|---|---|
committer | Gregory Terzian <gterzian@users.noreply.github.com> | 2019-08-20 14:28:36 +0200 |
commit | 9ddba756bfb19c9513eb84a80674aa4c23231799 (patch) | |
tree | f8d68a9a91a285d2577db45b3421f279a94b6599 /components/webdriver_server | |
parent | 17f423723c0206c934f104eb3352f39a9533aa41 (diff) | |
download | servo-9ddba756bfb19c9513eb84a80674aa4c23231799.tar.gz servo-9ddba756bfb19c9513eb84a80674aa4c23231799.zip |
use ipc router in webdriver
Diffstat (limited to 'components/webdriver_server')
-rw-r--r-- | components/webdriver_server/lib.rs | 67 |
1 files changed, 40 insertions, 27 deletions
diff --git a/components/webdriver_server/lib.rs b/components/webdriver_server/lib.rs index 0bd7d140c32..03a15db335d 100644 --- a/components/webdriver_server/lib.rs +++ b/components/webdriver_server/lib.rs @@ -7,6 +7,8 @@ #![deny(unsafe_code)] #[macro_use] +extern crate crossbeam_channel; +#[macro_use] extern crate log; #[macro_use] extern crate serde; @@ -19,11 +21,12 @@ mod capabilities; use crate::actions::InputSourceState; use base64; use capabilities::ServoCapabilities; -use crossbeam_channel::Sender; +use crossbeam_channel::{after, unbounded, Receiver, Sender}; use euclid::{Rect, Size2D}; use hyper::Method; use image::{DynamicImage, ImageFormat, RgbImage}; -use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; +use ipc_channel::ipc::{self, IpcSender}; +use ipc_channel::router::ROUTER; use keyboard_types::webdriver::send_keys; use msg::constellation_msg::{BrowsingContextId, TopLevelBrowsingContextId, TraversalDirection}; use pixels::PixelFormat; @@ -171,6 +174,14 @@ impl WebDriverSession { } struct Handler { + /// The threaded receiver on which we can block for a load-status. + /// It will receive messages sent on the load_status_sender, + /// and forwarded by the IPC router. + load_status_receiver: Receiver<LoadStatus>, + /// The IPC sender which we can clone and pass along to the constellation, + /// for it to send us a load-status. Messages sent on it + /// will be forwarded to the load_status_receiver. + load_status_sender: IpcSender<LoadStatus>, session: Option<WebDriverSession>, constellation_chan: Sender<ConstellationMsg>, resize_timeout: u32, @@ -371,7 +382,17 @@ impl<'de> Visitor<'de> for TupleVecMapVisitor { impl Handler { pub fn new(constellation_chan: Sender<ConstellationMsg>) -> Handler { + // Create a pair of both an IPC and a threaded channel, + // keep the IPC sender to clone and pass to the constellation for each load, + // and keep a threaded receiver to block on an incoming load-status. + // Pass the others to the IPC router so that IPC messages are forwarded to the threaded receiver. + // We need to use the router because IPC does not come with a timeout on receive/select. + let (load_status_sender, receiver) = ipc::channel().unwrap(); + let (sender, load_status_receiver) = unbounded(); + ROUTER.route_ipc_receiver_to_crossbeam_sender(receiver, sender); Handler { + load_status_sender, + load_status_receiver, session: None, constellation_chan: constellation_chan, resize_timeout: 500, @@ -613,35 +634,26 @@ impl Handler { let top_level_browsing_context_id = self.session()?.top_level_browsing_context_id; - let (sender, receiver) = ipc::channel().unwrap(); - let load_data = LoadData::new(LoadOrigin::WebDriver, url, None, None, None); - let cmd_msg = - WebDriverCommandMsg::LoadUrl(top_level_browsing_context_id, load_data, sender.clone()); + let cmd_msg = WebDriverCommandMsg::LoadUrl( + top_level_browsing_context_id, + load_data, + self.load_status_sender.clone(), + ); self.constellation_chan .send(ConstellationMsg::WebDriverCommand(cmd_msg)) .unwrap(); - self.wait_for_load(sender, receiver) + self.wait_for_load() } - fn wait_for_load( - &self, - sender: IpcSender<LoadStatus>, - receiver: IpcReceiver<LoadStatus>, - ) -> WebDriverResult<WebDriverResponse> { + fn wait_for_load(&self) -> WebDriverResult<WebDriverResponse> { let timeout = self.session()?.load_timeout; - thread::spawn(move || { - thread::sleep(Duration::from_millis(timeout)); - let _ = sender.send(LoadStatus::LoadTimeout); - }); - - // wait to get a load event - match receiver.recv().unwrap() { - LoadStatus::LoadComplete => Ok(WebDriverResponse::Void), - LoadStatus::LoadTimeout => { - Err(WebDriverError::new(ErrorStatus::Timeout, "Load timed out")) - }, + select! { + recv(self.load_status_receiver) -> _ => Ok(WebDriverResponse::Void), + recv(after(Duration::from_millis(timeout))) -> _ => Err( + WebDriverError::new(ErrorStatus::Timeout, "Load timed out") + ), } } @@ -775,14 +787,15 @@ impl Handler { fn handle_refresh(&self) -> WebDriverResult<WebDriverResponse> { let top_level_browsing_context_id = self.session()?.top_level_browsing_context_id; - let (sender, receiver) = ipc::channel().unwrap(); - - let cmd_msg = WebDriverCommandMsg::Refresh(top_level_browsing_context_id, sender.clone()); + let cmd_msg = WebDriverCommandMsg::Refresh( + top_level_browsing_context_id, + self.load_status_sender.clone(), + ); self.constellation_chan .send(ConstellationMsg::WebDriverCommand(cmd_msg)) .unwrap(); - self.wait_for_load(sender, receiver) + self.wait_for_load() } fn handle_title(&self) -> WebDriverResult<WebDriverResponse> { |