aboutsummaryrefslogtreecommitdiffstats
path: root/components/webdriver_server
diff options
context:
space:
mode:
authorGregory Terzian <gterzian@users.noreply.github.com>2019-08-19 21:57:12 +0200
committerGregory Terzian <gterzian@users.noreply.github.com>2019-08-20 14:28:36 +0200
commit9ddba756bfb19c9513eb84a80674aa4c23231799 (patch)
treef8d68a9a91a285d2577db45b3421f279a94b6599 /components/webdriver_server
parent17f423723c0206c934f104eb3352f39a9533aa41 (diff)
downloadservo-9ddba756bfb19c9513eb84a80674aa4c23231799.tar.gz
servo-9ddba756bfb19c9513eb84a80674aa4c23231799.zip
use ipc router in webdriver
Diffstat (limited to 'components/webdriver_server')
-rw-r--r--components/webdriver_server/lib.rs67
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> {