fix: Deno.emit crashes with BorrowMutError (#12627)

Warn on await_holding_refcell_ref clippy rule to avoid this in the future.

Fixes #12453
This commit is contained in:
Ryan Dahl 2021-11-03 09:27:36 -04:00 committed by GitHub
parent 95b2955712
commit 7c2abb9d57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 47 additions and 7 deletions

View File

@ -88,9 +88,15 @@ async fn op_emit(
) -> Result<EmitResult, AnyError> {
deno_runtime::ops::check_unstable2(&state, "Deno.emit");
let root_specifier = args.root_specifier;
let state = state.borrow();
let ps = state.borrow::<ProcState>();
let mut runtime_permissions = { state.borrow::<Permissions>().clone() };
let ps = {
let state = state.borrow();
state.borrow::<ProcState>().clone()
};
let mut runtime_permissions = {
let state = state.borrow();
state.borrow::<Permissions>().clone()
};
let mut cache: Box<dyn cache::CacherLoader> =
if let Some(sources) = &args.sources {
Box::new(cache::MemoryCacher::new(sources.clone()))

View File

@ -2148,3 +2148,21 @@ itest!(eval_context_throw_dom_exception {
args: "run eval_context_throw_dom_exception.js",
output: "eval_context_throw_dom_exception.js.out",
});
#[test]
fn issue12453() {
let _g = util::http_server();
let deno_dir = util::new_deno_dir();
let mut deno_cmd = util::deno_cmd_with_deno_dir(deno_dir.path());
let status = deno_cmd
.current_dir(util::testdata_path())
.arg("run")
.arg("--unstable")
.arg("--allow-net")
.arg("issue12453.js")
.spawn()
.unwrap()
.wait()
.unwrap();
assert!(status.success());
}

4
cli/tests/testdata/issue12453.js vendored Normal file
View File

@ -0,0 +1,4 @@
const i = setInterval(() => {
Deno.emit("http://localhost:4545/subdir/mt_text_typescript.t1.ts");
clearInterval(i);
}, 1);

View File

@ -2317,11 +2317,14 @@ assertEquals(1, notify_return_value);
_: (),
_: (),
) -> Result<(), AnyError> {
let op_state = op_state.borrow();
let inner_state = op_state.borrow::<InnerState>();
let n = {
let op_state = op_state.borrow();
let inner_state = op_state.borrow::<InnerState>();
inner_state.0
};
// Future must be Poll::Pending on first call
tokio::time::sleep(std::time::Duration::from_millis(1)).await;
if inner_state.0 != 42 {
if n != 42 {
unreachable!();
}
Ok(())

View File

@ -48,6 +48,7 @@ impl MessagePort {
&self,
state: Rc<RefCell<OpState>>,
) -> Result<Option<JsMessageData>, AnyError> {
#![allow(clippy::await_holding_refcell_ref)] // TODO(ry) remove!
let mut rx = self
.rx
.try_borrow_mut()

View File

@ -198,6 +198,7 @@ impl WebWorkerHandle {
pub async fn get_control_event(
&self,
) -> Result<Option<WorkerControlEvent>, AnyError> {
#![allow(clippy::await_holding_refcell_ref)] // TODO(ry) remove!
let mut receiver = self.receiver.borrow_mut();
Ok(receiver.next().await)
}

View File

@ -109,7 +109,14 @@ async function clippy() {
}
const p = Deno.run({
cmd: [...cmd, "--", "-D", "clippy::all"],
cmd: [
...cmd,
"--",
"-D",
"clippy::all",
"-D",
"clippy::await_holding_refcell_ref",
],
});
const { success } = await p.status();
if (!success) {