Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wasm] Make runtime_is_initialized promise callbacks one-shot #70694

Merged
merged 3 commits into from
Jun 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/mono/wasm/runtime/guarded-promise.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

/// A Promise<T> that guards against multiple-resolve, multiple-reject, reject-after-accept and accept-after-reject.
lambdageek marked this conversation as resolved.
Show resolved Hide resolved
class GuardedPromise<T> extends Promise<T> {
constructor(executor: (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void) {
super((resolve, reject) => {
let resolved = false;
let rejected = false;
executor((value: T | PromiseLike<T>) => {
if (resolved) {
throw new Error("Promise resolved more than once");
}
if (rejected) {
throw new Error("Can not resolve a Promise after it has been rejected");
}
resolved = true;
resolve(value);
}, (reason: any) => {
if (resolved) {
throw new Error("Can not reject a Promise after it has been resolved");
}
if (rejected) {
throw new Error("Promise rejected more than once");
}
rejected = true;
reject(reason);
});
});
}
}

export default GuardedPromise;

7 changes: 4 additions & 3 deletions src/mono/wasm/runtime/startup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { AllAssetEntryTypes, mono_assert, AssetEntry, CharPtrNull, DotnetModule,
import { ENVIRONMENT_IS_ESM, ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, INTERNAL, locateFile, Module, MONO, requirePromise, runtimeHelpers } from "./imports";
import cwraps from "./cwraps";
import { mono_wasm_raise_debug_event, mono_wasm_runtime_ready } from "./debug";
import GuardedPromise from "./guarded-promise";
import { mono_wasm_globalization_init, mono_wasm_load_icu_data } from "./icu";
import { toBase64StringImpl } from "./base64";
import { mono_wasm_init_aot_profiler, mono_wasm_init_coverage_profiler } from "./profiler";
Expand All @@ -17,9 +18,9 @@ import { mono_on_abort } from "./run";
import { mono_wasm_new_root } from "./roots";
import { init_crypto } from "./crypto-worker";

export let runtime_is_initialized_resolve: Function;
export let runtime_is_initialized_reject: Function;
export const mono_wasm_runtime_is_initialized = new Promise((resolve, reject) => {
export let runtime_is_initialized_resolve: () => void;
export let runtime_is_initialized_reject: (reason?: any) => void;
export const mono_wasm_runtime_is_initialized = new GuardedPromise<void>((resolve, reject) => {
runtime_is_initialized_resolve = resolve;
runtime_is_initialized_reject = reject;
});
Expand Down