summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoshiya Hinosawa <stibium121@gmail.com>2021-01-21 16:44:48 +0900
committerGitHub <noreply@github.com>2021-01-21 16:44:48 +0900
commit18ac7d40c87b380ce5ed617bd7c59e344730a883 (patch)
tree2588d833bed775c22756db9e18742ec736e498da
parent8bef29fd74f24e3682069a1188386d90805a9904 (diff)
fix(runtime): fix recursive dispatches of unload event (#9207)
-rw-r--r--cli/tests/078_unload_on_exit.ts5
-rw-r--r--cli/tests/integration_tests.rs1
-rw-r--r--runtime/js/30_os.js9
-rw-r--r--runtime/js/99_main.js9
4 files changed, 21 insertions, 3 deletions
diff --git a/cli/tests/078_unload_on_exit.ts b/cli/tests/078_unload_on_exit.ts
index e8288ef31..43d33eb25 100644
--- a/cli/tests/078_unload_on_exit.ts
+++ b/cli/tests/078_unload_on_exit.ts
@@ -1,4 +1,9 @@
window.onunload = () => {
console.log("onunload is called");
+ // This second exit call doesn't trigger unload event,
+ // and therefore actually stops the process.
+ Deno.exit(1);
+ console.log("This doesn't show up in console");
};
+// This exit call triggers the above unload event handler.
Deno.exit(0);
diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs
index be7bb63c5..428d1ff30 100644
--- a/cli/tests/integration_tests.rs
+++ b/cli/tests/integration_tests.rs
@@ -2665,6 +2665,7 @@ itest!(_077_fetch_empty {
itest!(_078_unload_on_exit {
args: "run 078_unload_on_exit.ts",
output: "078_unload_on_exit.ts.out",
+ exit_code: 1,
});
itest!(_079_location_authentication {
diff --git a/runtime/js/30_os.js b/runtime/js/30_os.js
index 1d700b561..5a3c990b0 100644
--- a/runtime/js/30_os.js
+++ b/runtime/js/30_os.js
@@ -24,9 +24,12 @@
}
function exit(code = 0) {
- // Invokes the `unload` hooks before exiting
- // ref: https://github.com/denoland/deno/issues/3603
- window.dispatchEvent(new Event("unload"));
+ // Dispatches `unload` only when it's not dispatched yet.
+ if (!window[Symbol.for("isUnloadDispatched")]) {
+ // Invokes the `unload` hooks before exiting
+ // ref: https://github.com/denoland/deno/issues/3603
+ window.dispatchEvent(new Event("unload"));
+ }
core.jsonOpSync("op_exit", { code });
throw new Error("Code not reachable");
}
diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js
index a6abc8d27..fd846af20 100644
--- a/runtime/js/99_main.js
+++ b/runtime/js/99_main.js
@@ -305,6 +305,15 @@ delete Object.prototype.__proto__;
defineEventHandler(window, "load", null);
defineEventHandler(window, "unload", null);
+ const isUnloadDispatched = Symbol.for("isUnloadDispatched");
+ // Stores the flag for checking whether unload is dispatched or not.
+ // This prevents the recursive dispatches of unload events.
+ // See https://github.com/denoland/deno/issues/9201.
+ window[isUnloadDispatched] = false;
+ window.addEventListener("unload", () => {
+ window[isUnloadDispatched] = true;
+ });
+
runtimeStart(runtimeOptions);
const {
args,