Fix already borrowed error in webdriver

This commit is contained in:
George Roman 2019-06-09 22:25:41 +03:00
parent 347d8bdf72
commit 1dda774518
2 changed files with 46 additions and 41 deletions

View file

@ -1833,6 +1833,22 @@ impl ScriptThread {
} }
fn handle_webdriver_msg(&self, pipeline_id: PipelineId, msg: WebDriverScriptCommand) { fn handle_webdriver_msg(&self, pipeline_id: PipelineId, msg: WebDriverScriptCommand) {
// https://github.com/servo/servo/issues/23535
// These two messages need different treatment since the JS script might mutate
// `self.documents`, which would conflict with the immutable borrow of it that
// occurs for the rest of the messages
match msg {
WebDriverScriptCommand::ExecuteScript(script, reply) => {
let window = { self.documents.borrow().find_window(pipeline_id) };
return webdriver_handlers::handle_execute_script(window, script, reply);
},
WebDriverScriptCommand::ExecuteAsyncScript(script, reply) => {
let window = { self.documents.borrow().find_window(pipeline_id) };
return webdriver_handlers::handle_execute_async_script(window, script, reply);
},
_ => (),
}
let documents = self.documents.borrow(); let documents = self.documents.borrow();
match msg { match msg {
WebDriverScriptCommand::AddCookie(params, reply) => { WebDriverScriptCommand::AddCookie(params, reply) => {
@ -1841,9 +1857,6 @@ impl ScriptThread {
WebDriverScriptCommand::DeleteCookies(reply) => { WebDriverScriptCommand::DeleteCookies(reply) => {
webdriver_handlers::handle_delete_cookies(&*documents, pipeline_id, reply) webdriver_handlers::handle_delete_cookies(&*documents, pipeline_id, reply)
}, },
WebDriverScriptCommand::ExecuteScript(script, reply) => {
webdriver_handlers::handle_execute_script(&*documents, pipeline_id, script, reply)
},
WebDriverScriptCommand::FindElementCSS(selector, reply) => { WebDriverScriptCommand::FindElementCSS(selector, reply) => {
webdriver_handlers::handle_find_element_css( webdriver_handlers::handle_find_element_css(
&*documents, &*documents,
@ -1936,14 +1949,7 @@ impl ScriptThread {
WebDriverScriptCommand::GetTitle(reply) => { WebDriverScriptCommand::GetTitle(reply) => {
webdriver_handlers::handle_get_title(&*documents, pipeline_id, reply) webdriver_handlers::handle_get_title(&*documents, pipeline_id, reply)
}, },
WebDriverScriptCommand::ExecuteAsyncScript(script, reply) => { _ => (),
webdriver_handlers::handle_execute_async_script(
&*documents,
pipeline_id,
script,
reply,
)
},
} }
} }

View file

@ -23,6 +23,7 @@ use crate::dom::htmliframeelement::HTMLIFrameElement;
use crate::dom::htmlinputelement::HTMLInputElement; use crate::dom::htmlinputelement::HTMLInputElement;
use crate::dom::htmloptionelement::HTMLOptionElement; use crate::dom::htmloptionelement::HTMLOptionElement;
use crate::dom::node::{window_from_node, Node, ShadowIncluding}; use crate::dom::node::{window_from_node, Node, ShadowIncluding};
use crate::dom::window::Window;
use crate::script_thread::Documents; use crate::script_thread::Documents;
use cookie::Cookie; use cookie::Cookie;
use euclid::{Point2D, Rect, Size2D}; use euclid::{Point2D, Rect, Size2D};
@ -87,53 +88,51 @@ pub unsafe fn jsval_to_webdriver(cx: *mut JSContext, val: HandleValue) -> WebDri
#[allow(unsafe_code)] #[allow(unsafe_code)]
pub fn handle_execute_script( pub fn handle_execute_script(
documents: &Documents, window: Option<DomRoot<Window>>,
pipeline: PipelineId,
eval: String, eval: String,
reply: IpcSender<WebDriverJSResult>, reply: IpcSender<WebDriverJSResult>,
) { ) {
let window = match documents.find_window(pipeline) { match window {
Some(window) => window, Some(window) => {
let result = unsafe {
let cx = window.get_cx();
rooted!(in(cx) let mut rval = UndefinedValue());
window
.upcast::<GlobalScope>()
.evaluate_js_on_global_with_result(&eval, rval.handle_mut());
jsval_to_webdriver(cx, rval.handle())
};
reply.send(result).unwrap();
},
None => { None => {
return reply reply
.send(Err(WebDriverJSError::BrowsingContextNotFound)) .send(Err(WebDriverJSError::BrowsingContextNotFound))
.unwrap(); .unwrap();
}, },
}; }
let result = unsafe {
let cx = window.get_cx();
rooted!(in(cx) let mut rval = UndefinedValue());
window
.upcast::<GlobalScope>()
.evaluate_js_on_global_with_result(&eval, rval.handle_mut());
jsval_to_webdriver(cx, rval.handle())
};
reply.send(result).unwrap();
} }
pub fn handle_execute_async_script( pub fn handle_execute_async_script(
documents: &Documents, window: Option<DomRoot<Window>>,
pipeline: PipelineId,
eval: String, eval: String,
reply: IpcSender<WebDriverJSResult>, reply: IpcSender<WebDriverJSResult>,
) { ) {
let window = match documents.find_window(pipeline) { match window {
Some(window) => window, Some(window) => {
let cx = window.get_cx();
window.set_webdriver_script_chan(Some(reply));
rooted!(in(cx) let mut rval = UndefinedValue());
window
.upcast::<GlobalScope>()
.evaluate_js_on_global_with_result(&eval, rval.handle_mut());
},
None => { None => {
return reply reply
.send(Err(WebDriverJSError::BrowsingContextNotFound)) .send(Err(WebDriverJSError::BrowsingContextNotFound))
.unwrap(); .unwrap();
}, },
}; }
let cx = window.get_cx();
window.set_webdriver_script_chan(Some(reply));
rooted!(in(cx) let mut rval = UndefinedValue());
window
.upcast::<GlobalScope>()
.evaluate_js_on_global_with_result(&eval, rval.handle_mut());
} }
pub fn handle_get_browsing_context_id( pub fn handle_get_browsing_context_id(