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

[browser][MT] assert no managed transition on UI thread after start #100410

Merged
merged 8 commits into from
Apr 3, 2024
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
3 changes: 3 additions & 0 deletions src/mono/browser/runtime/exports-internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ export function cwraps_internal (internal: any): void {

/* @deprecated not GC safe, legacy support for Blazor */
export function monoObjectAsBoolOrNullUnsafe (obj: MonoObject): boolean | null {
// TODO https://github.com/dotnet/runtime/issues/100411
// after Blazor stops using monoObjectAsBoolOrNullUnsafe

if (obj === MonoObjectNull) {
return null;
}
Expand Down
3 changes: 3 additions & 0 deletions src/mono/browser/runtime/gc-lock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import cwraps from "./cwraps";

export let gc_locked = false;

// TODO https://github.com/dotnet/runtime/issues/100411
// after Blazor stops using mono_wasm_gc_lock, mono_wasm_gc_unlock

export function mono_wasm_gc_lock (): void {
if (gc_locked) {
throw new Error("GC is already locked");
Expand Down
6 changes: 3 additions & 3 deletions src/mono/browser/runtime/marshal-to-cs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import { _zero_region, localHeapViewF64, localHeapViewI32, localHeapViewU8 } fro
import { stringToMonoStringRoot, stringToUTF16 } from "./strings";
import { JSMarshalerArgument, JSMarshalerArguments, JSMarshalerType, MarshalerToCs, MarshalerToJs, BoundMarshalerToCs, MarshalerType } from "./types/internal";
import { TypedArray } from "./types/emscripten";
import { gc_locked } from "./gc-lock";

export const jsinteropDoc = "For more information see https://aka.ms/dotnet-wasm-jsinterop";

Expand Down Expand Up @@ -224,6 +223,7 @@ function _marshal_string_to_cs_impl (arg: JSMarshalerArgument, value: string) {
set_arg_intptr(arg, buffer);
set_arg_length(arg, value.length);
} else {
mono_assert(!WasmEnableThreads, "Marshaling strings by reference is not supported in multithreaded mode");
const root = get_string_root(arg);
try {
stringToMonoStringRoot(value, root);
Expand Down Expand Up @@ -463,7 +463,7 @@ export function marshal_array_to_cs_impl (arg: JSMarshalerArgument, value: Array
mono_check(Array.isArray(value), "Value is not an Array");
_zero_region(buffer_ptr, buffer_length);
if (!WasmEnableJsInteropByValue) {
mono_assert(!WasmEnableThreads || !gc_locked, "GC must not be locked when creating a GC root");
mono_assert(!WasmEnableThreads, "Marshaling strings by reference is not supported in multithreaded mode");
cwraps.mono_wasm_register_root(buffer_ptr, buffer_length, "marshal_array_to_cs");
}
for (let index = 0; index < length; index++) {
Expand All @@ -474,7 +474,7 @@ export function marshal_array_to_cs_impl (arg: JSMarshalerArgument, value: Array
mono_check(Array.isArray(value), "Value is not an Array");
_zero_region(buffer_ptr, buffer_length);
if (!WasmEnableJsInteropByValue) {
mono_assert(!WasmEnableThreads || !gc_locked, "GC must not be locked when creating a GC root");
mono_assert(!WasmEnableThreads, "Marshaling objects by reference is not supported in multithreaded mode");
cwraps.mono_wasm_register_root(buffer_ptr, buffer_length, "marshal_array_to_cs");
}
for (let index = 0; index < length; index++) {
Expand Down
6 changes: 3 additions & 3 deletions src/mono/browser/runtime/marshal-to-js.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import { TypedArray } from "./types/emscripten";
import { get_marshaler_to_cs_by_type, jsinteropDoc, marshal_exception_to_cs } from "./marshal-to-cs";
import { localHeapViewF64, localHeapViewI32, localHeapViewU8 } from "./memory";
import { call_delegate } from "./managed-exports";
import { gc_locked } from "./gc-lock";
import { mono_log_debug } from "./logging";
import { invoke_later_when_on_ui_thread_async } from "./invoke-js";

Expand Down Expand Up @@ -390,6 +389,7 @@ export function marshal_string_to_js (arg: JSMarshalerArgument): string | null {
Module._free(buffer as any);
return value;
} else {
mono_assert(!WasmEnableThreads, "Marshaling strings by reference is not supported in multithreaded mode");
const root = get_string_root(arg);
try {
const value = monoStringToString(root);
Expand Down Expand Up @@ -504,7 +504,7 @@ function _marshal_array_to_js_impl (arg: JSMarshalerArgument, element_type: Mars
result[index] = marshal_string_to_js(element_arg);
}
if (!WasmEnableJsInteropByValue) {
mono_assert(!WasmEnableThreads || !gc_locked, "GC must not be locked when disposing a GC root");
mono_assert(!WasmEnableThreads, "Marshaling string by reference is not supported in multithreaded mode");
cwraps.mono_wasm_deregister_root(<any>buffer_ptr);
}
} else if (element_type == MarshalerType.Object) {
Expand All @@ -514,7 +514,7 @@ function _marshal_array_to_js_impl (arg: JSMarshalerArgument, element_type: Mars
result[index] = _marshal_cs_object_to_js(element_arg);
}
if (!WasmEnableJsInteropByValue) {
mono_assert(!WasmEnableThreads || !gc_locked, "GC must not be locked when disposing a GC root");
mono_assert(!WasmEnableThreads, "Marshaling objects by reference is not supported in multithreaded mode");
cwraps.mono_wasm_deregister_root(<any>buffer_ptr);
}
} else if (element_type == MarshalerType.JSObject) {
Expand Down
5 changes: 4 additions & 1 deletion src/mono/browser/runtime/roots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import WasmEnableThreads from "consts:wasmEnableThreads";

import cwraps from "./cwraps";
import { Module, mono_assert } from "./globals";
import { Module, mono_assert, runtimeHelpers } from "./globals";
import { VoidPtr, ManagedPointer, NativePointer } from "./types/emscripten";
import { MonoObjectRef, MonoObjectRefNull, MonoObject, is_nullish, WasmRoot, WasmRootBuffer } from "./types/internal";
import { _zero_region, localHeapViewU32 } from "./memory";
Expand All @@ -24,6 +24,7 @@ const _external_root_free_instances: WasmExternalRoot<any>[] = [];
* For small numbers of roots, it is preferable to use the mono_wasm_new_root and mono_wasm_new_roots APIs instead.
*/
export function mono_wasm_new_root_buffer (capacity: number, name?: string): WasmRootBuffer {
if (WasmEnableThreads && runtimeHelpers.disableManagedTransition) throw new Error("External roots are not supported when threads are enabled");
if (capacity <= 0)
throw new Error("capacity >= 1");

Expand All @@ -44,6 +45,7 @@ export function mono_wasm_new_root_buffer (capacity: number, name?: string): Was
* Releasing this root will not de-allocate the root space. You still need to call .release().
*/
export function mono_wasm_new_external_root<T extends MonoObject> (address: VoidPtr | MonoObjectRef): WasmRoot<T> {
if (WasmEnableThreads && runtimeHelpers.disableManagedTransition) throw new Error("External roots are not supported in multithreaded mode");
let result: WasmExternalRoot<T>;

if (!address)
Expand All @@ -67,6 +69,7 @@ export function mono_wasm_new_external_root<T extends MonoObject> (address: Void
* When you are done using the root you must call its .release() method.
*/
export function mono_wasm_new_root<T extends MonoObject> (value: T | undefined = undefined): WasmRoot<T> {
if (WasmEnableThreads && runtimeHelpers.disableManagedTransition) throw new Error("External roots are not supported in multithreaded mode");
let result: WasmRoot<T>;

if (_scratch_root_free_instances.length > 0) {
Expand Down
4 changes: 3 additions & 1 deletion src/mono/browser/runtime/startup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,14 +288,16 @@ async function onRuntimeInitializedAsync (userOnRuntimeInitialized: () => void)
runtimeHelpers.ioThreadTID = tcwraps.mono_wasm_create_io_thread();
}

// TODO make UI thread not managed
// TODO make UI thread not managed/attached https://github.com/dotnet/runtime/issues/100411
tcwraps.mono_wasm_register_ui_thread();
monoThreadInfo.isAttached = true;
monoThreadInfo.isRegistered = true;

runtimeHelpers.runtimeReady = true;
update_thread_info();
bindings_init();

runtimeHelpers.disableManagedTransition = true;
} else {
// load mono runtime and apply environment settings (if necessary)
await start_runtime();
Expand Down
7 changes: 7 additions & 0 deletions src/mono/browser/runtime/strings.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

import WasmEnableThreads from "consts:wasmEnableThreads";

import { mono_wasm_new_root, mono_wasm_new_root_buffer } from "./roots";
import { MonoString, MonoStringNull, WasmRoot, WasmRootBuffer } from "./types/internal";
import { Module } from "./globals";
Expand Down Expand Up @@ -118,6 +120,10 @@ export function stringToUTF16Ptr (str: string): VoidPtr {
}

export function monoStringToString (root: WasmRoot<MonoString>): string | null {
// TODO https://github.com/dotnet/runtime/issues/100411
// after Blazor stops using monoStringToStringUnsafe
// mono_assert(!WasmEnableThreads, "Marshaling strings by reference is not supported in multithreaded mode");

if (root.value === MonoStringNull)
return null;

Expand Down Expand Up @@ -152,6 +158,7 @@ export function monoStringToString (root: WasmRoot<MonoString>): string | null {
}

export function stringToMonoStringRoot (string: string, result: WasmRoot<MonoString>): void {
if (WasmEnableThreads) return;
result.clear();

if (string === null)
Expand Down
1 change: 1 addition & 0 deletions src/mono/browser/runtime/types/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ export type RuntimeHelpers = {
getMemory(): WebAssembly.Memory,
getWasmIndirectFunctionTable(): WebAssembly.Table,
runtimeReady: boolean,
disableManagedTransition: boolean,
monoThreadInfo: PThreadInfo,
proxyGCHandle: GCHandle | undefined,
managedThreadTID: PThreadPtr,
Expand Down
Loading