diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2020-11-27 14:19:24 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-27 14:19:24 +0100 |
commit | 22f951aa67c5b677d156ec338f71714cf2d4ddb2 (patch) | |
tree | 58537dffb4aa0f3c3b2a348c99466cb89919c835 | |
parent | 28869a632d190dc29d78738bc5e90eadf99bc824 (diff) |
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.
-rw-r--r-- | cli/tests/immediately_close_worker.js | 1 | ||||
-rw-r--r-- | cli/tests/integration_tests.rs | 5 | ||||
-rw-r--r-- | cli/tests/no_mem_cache.js | 33 | ||||
-rw-r--r-- | cli/tests/no_mem_cache.js.out | 2 | ||||
-rw-r--r-- | cli/tests/workers_test.ts | 16 | ||||
-rw-r--r-- | core/runtime.rs | 10 |
6 files changed, 64 insertions, 3 deletions
diff --git a/cli/tests/immediately_close_worker.js b/cli/tests/immediately_close_worker.js new file mode 100644 index 000000000..8fd27343a --- /dev/null +++ b/cli/tests/immediately_close_worker.js @@ -0,0 +1 @@ +self.close(); diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index afe030a03..a7e901d83 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -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; diff --git a/cli/tests/no_mem_cache.js b/cli/tests/no_mem_cache.js new file mode 100644 index 000000000..a486732b6 --- /dev/null +++ b/cli/tests/no_mem_cache.js @@ -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(); diff --git a/cli/tests/no_mem_cache.js.out b/cli/tests/no_mem_cache.js.out new file mode 100644 index 000000000..a32119c8a --- /dev/null +++ b/cli/tests/no_mem_cache.js.out @@ -0,0 +1,2 @@ +hello +goodbye diff --git a/cli/tests/workers_test.ts b/cli/tests/workers_test.ts index e5b0eaa74..d907c97a9 100644 --- a/cli/tests/workers_test.ts +++ b/cli/tests/workers_test.ts @@ -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(); + }, +}); diff --git a/core/runtime.rs b/core/runtime.rs index 873167388..7f71af09a 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -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 |