mirror of
https://github.com/denoland/deno.git
synced 2025-01-03 04:48:52 -05:00
fix: panic in worker when closing at top level (#8510)
Fixes panic occurring in worker when "self.close()" is called at the top level, ie. worker shuts down while module evaluation promise hasn't yet resolved.
This commit is contained in:
parent
28869a632d
commit
22f951aa67
6 changed files with 64 additions and 3 deletions
1
cli/tests/immediately_close_worker.js
Normal file
1
cli/tests/immediately_close_worker.js
Normal file
|
@ -0,0 +1 @@
|
|||
self.close();
|
|
@ -3273,6 +3273,11 @@ itest!(ignore_require {
|
|||
exit_code: 0,
|
||||
});
|
||||
|
||||
itest!(local_sources_not_cached_in_memory {
|
||||
args: "run --allow-read --allow-write no_mem_cache.js",
|
||||
output: "no_mem_cache.js.out",
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn cafile_env_fetch() {
|
||||
use deno_core::url::Url;
|
||||
|
|
33
cli/tests/no_mem_cache.js
Normal file
33
cli/tests/no_mem_cache.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
const fixtureFile = await Deno.makeTempFile();
|
||||
let prefix = "file://";
|
||||
if (Deno.build.os == "windows") {
|
||||
prefix += "/";
|
||||
}
|
||||
const fixtureUrl = new URL(`${prefix}${fixtureFile}`);
|
||||
let resolve;
|
||||
|
||||
let p = new Promise((res) => resolve = res);
|
||||
|
||||
await Deno.writeTextFile(fixtureUrl, `self.postMessage("hello");\n`);
|
||||
|
||||
const workerA = new Worker(fixtureUrl.href, { type: "module" });
|
||||
workerA.onmessage = (msg) => {
|
||||
console.log(msg.data);
|
||||
resolve();
|
||||
};
|
||||
|
||||
await p;
|
||||
workerA.terminate();
|
||||
|
||||
p = new Promise((res) => resolve = res);
|
||||
|
||||
await Deno.writeTextFile(fixtureUrl, `self.postMessage("goodbye");\n`);
|
||||
|
||||
const workerB = new Worker(fixtureUrl.href, { type: "module" });
|
||||
workerB.onmessage = (msg) => {
|
||||
console.log(msg.data);
|
||||
resolve();
|
||||
};
|
||||
|
||||
await p;
|
||||
workerB.terminate();
|
2
cli/tests/no_mem_cache.js.out
Normal file
2
cli/tests/no_mem_cache.js.out
Normal file
|
@ -0,0 +1,2 @@
|
|||
hello
|
||||
goodbye
|
|
@ -341,3 +341,19 @@ Deno.test({
|
|||
w.terminate();
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Worker immediate close",
|
||||
fn: async function (): Promise<void> {
|
||||
const promise = deferred();
|
||||
const w = new Worker(
|
||||
new URL("./immediately_close_worker.js", import.meta.url).href,
|
||||
{ type: "module" },
|
||||
);
|
||||
setTimeout(() => {
|
||||
promise.resolve();
|
||||
}, 1000);
|
||||
await promise;
|
||||
w.terminate();
|
||||
},
|
||||
});
|
||||
|
|
|
@ -901,9 +901,13 @@ impl JsRuntime {
|
|||
let mut receiver = self.mod_evaluate_inner(id)?;
|
||||
|
||||
poll_fn(|cx| {
|
||||
if let Poll::Ready(result) = receiver.poll_next_unpin(cx) {
|
||||
debug!("received module evaluate");
|
||||
return Poll::Ready(result.unwrap());
|
||||
if let Poll::Ready(maybe_result) = receiver.poll_next_unpin(cx) {
|
||||
debug!("received module evaluate {:#?}", maybe_result);
|
||||
// If `None` is returned it means that runtime was destroyed before
|
||||
// evaluation was complete. This can happen in Web Worker when `self.close()`
|
||||
// is called at top level.
|
||||
let result = maybe_result.unwrap_or(Ok(()));
|
||||
return Poll::Ready(result);
|
||||
}
|
||||
let _r = self.poll_event_loop(cx)?;
|
||||
Poll::Pending
|
||||
|
|
Loading…
Reference in a new issue