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

testing GC handle #99403

Closed
Closed
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
1,495 changes: 0 additions & 1,495 deletions eng/pipelines/runtime.yml

Large diffs are not rendered by default.

47 changes: 0 additions & 47 deletions eng/testing/scenarios/BuildWasmAppsJobsList.txt
Original file line number Diff line number Diff line change
@@ -1,48 +1 @@
Wasm.Build.NativeRebuild.Tests.FlagsChangeRebuildTests
Wasm.Build.NativeRebuild.Tests.NoopNativeRebuildTest
Wasm.Build.NativeRebuild.Tests.OptimizationFlagChangeTests
Wasm.Build.NativeRebuild.Tests.ReferenceNewAssemblyRebuildTest
Wasm.Build.NativeRebuild.Tests.SimpleSourceChangeRebuildTest
Wasm.Build.Templates.Tests.InterpPgoTests
Wasm.Build.Templates.Tests.NativeBuildTests
Wasm.Build.Tests.Blazor.AppsettingsTests
Wasm.Build.Tests.Blazor.BuildPublishTests
Wasm.Build.Tests.Blazor.SimpleRunTests
Wasm.Build.Tests.Blazor.CleanTests
Wasm.Build.Tests.Blazor.MiscTests
Wasm.Build.Tests.Blazor.MiscTests2
Wasm.Build.Tests.Blazor.MiscTests3
Wasm.Build.Tests.Blazor.NativeTests
Wasm.Build.Tests.Blazor.NoopNativeRebuildTest
Wasm.Build.Tests.Blazor.WorkloadRequiredTests
Wasm.Build.Tests.Blazor.IcuTests
Wasm.Build.Tests.Blazor.IcuShardingTests
Wasm.Build.Tests.BuildPublishTests
Wasm.Build.Tests.ConfigSrcTests
Wasm.Build.Tests.HybridGlobalizationTests
Wasm.Build.Tests.IcuShardingTests
Wasm.Build.Tests.IcuShardingTests2
Wasm.Build.Tests.IcuTests
Wasm.Build.Tests.InvariantGlobalizationTests
Wasm.Build.Tests.InvariantTimezoneTests
Wasm.Build.Tests.MainWithArgsTests
Wasm.Build.Tests.NativeBuildTests
Wasm.Build.Tests.NativeLibraryTests
Wasm.Build.Tests.NonWasmTemplateBuildTests
Wasm.Build.Tests.PInvokeTableGeneratorTests
Wasm.Build.Tests.RebuildTests
Wasm.Build.Tests.SatelliteAssembliesTests
Wasm.Build.Tests.TestAppScenarios.AppSettingsTests
Wasm.Build.Tests.TestAppScenarios.LazyLoadingTests
Wasm.Build.Tests.TestAppScenarios.LibraryInitializerTests
Wasm.Build.Tests.TestAppScenarios.SatelliteLoadingTests
Wasm.Build.Tests.TestAppScenarios.DownloadResourceProgressTests
Wasm.Build.Tests.TestAppScenarios.SignalRClientTests
Wasm.Build.Tests.WasmBuildAppTest
Wasm.Build.Tests.WasmNativeDefaultsTests
Wasm.Build.Tests.WasmRunOutOfAppBundleTests
Wasm.Build.Tests.WasmSIMDTests
Wasm.Build.Tests.WasmTemplateTests
Wasm.Build.Tests.WorkloadTests
Wasm.Build.Tests.MT.Blazor.SimpleMultiThreadedTests
Wasm.Build.Tests.TestAppScenarios.DebugLevelTests
2 changes: 1 addition & 1 deletion src/libraries/sendtohelix-wasm.targets
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Import Project="$(RepositoryEngineeringDir)testing\workloads-testing.targets" />

<PropertyGroup>
<_workItemTimeout Condition="'$(Scenario)' == 'BuildWasmApps' and '$(_workItemTimeout)' == ''">01:30:00</_workItemTimeout>
<_workItemTimeout Condition="'$(Scenario)' == 'BuildWasmApps' and '$(_workItemTimeout)' == ''">00:20:00</_workItemTimeout>
<_workItemTimeout Condition="'$(NeedsToBuildWasmAppsOnHelix)' == 'true'">01:00:00</_workItemTimeout>

<BrowserBuildTargetsDir>$([MSBuild]::NormalizeDirectory($(BrowserProjectRoot), 'build'))</BrowserBuildTargetsDir>
Expand Down
13 changes: 12 additions & 1 deletion src/mono/browser/runtime/cancelable-promise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { createPromiseController, loaderHelpers, mono_assert } from "./globals";
import { ControllablePromise, GCHandle, MarshalerToCs } from "./types/internal";
import { ManagedObject } from "./marshal";
import { compareExchangeI32, forceThreadMemoryViewRefresh } from "./memory";
import { mono_log_debug } from "./logging";
import { mono_log_debug, mono_log_warn } from "./logging";
import { settleUnsettledPromise } from "./pthreads";
import { complete_task } from "./managed-exports";
import { marshal_cs_object_to_cs } from "./marshal-to-cs";
Expand Down Expand Up @@ -63,17 +63,22 @@ export class PromiseHolder extends ManagedObject {

// returns false if the promise is being canceled by another thread in managed code
setIsResolving(): boolean {
mono_log_warn("setIsResolving A " + this.gc_handle + " at " + this.promiseHolderPtr);
if (!WasmEnableThreads || this.promiseHolderPtr === 0) {
mono_log_warn("setIsResolving A " + this.gc_handle);
return true;
}
forceThreadMemoryViewRefresh();
if (compareExchangeI32(this.promiseHolderPtr + PromiseHolderState.IsResolving, 1, 0) === 0) {
mono_log_warn("setIsResolving B " + this.gc_handle);
return true;
}
mono_log_warn("setIsResolving C " + this.gc_handle);
return false;
}

resolve(data: any) {
mono_log_warn("resolve " + this.gc_handle + " \n" + new Error().stack);
mono_assert(!this.isResolved, "resolve could be called only once");
if (WasmEnableThreads && !this.setIsResolving()) {
// we know that cancelation is in flight
Expand All @@ -82,6 +87,7 @@ export class PromiseHolder extends ManagedObject {
// we store the original data and use it later
this.data = data;
this.isPostponed = true;
mono_log_warn("resolve isPostponed" + this.gc_handle);

// but after the promise is resolved, nothing holds the weak reference to the PromiseHolder anymore
// we know that cancelation is in flight, so we upgrade the weak reference to strong for the meantime
Expand All @@ -93,6 +99,7 @@ export class PromiseHolder extends ManagedObject {
}

reject(reason: any) {
mono_log_warn("reject " + this.gc_handle + " \n" + new Error().stack);
mono_assert(!this.isResolved, "reject could be called only once");
const isCancelation = reason && reason[promise_holder_symbol] === this;
if (WasmEnableThreads && !isCancelation && !this.setIsResolving()) {
Expand All @@ -102,6 +109,7 @@ export class PromiseHolder extends ManagedObject {
// we store the original reason and use it later
this.reason = reason;
this.isPostponed = true;
mono_log_warn("reject isPostponed" + this.gc_handle);

// but after the promise is resolved, nothing holds the weak reference to the PromiseHolder anymore
// we know that cancelation is in flight, so we upgrade the weak reference to strong for the meantime
Expand All @@ -113,6 +121,8 @@ export class PromiseHolder extends ManagedObject {
}

cancel() {
mono_log_warn("cancel " + this.gc_handle + " \n" + new Error().stack);

mono_assert(!this.isResolved, "cancel could be called only once");

if (this.isPostponed) {
Expand Down Expand Up @@ -151,6 +161,7 @@ export class PromiseHolder extends ManagedObject {
settleUnsettledPromise();
}

mono_log_warn("complete_task " + this.gc_handle + " \n" + new Error().stack);
// we can unregister the GC handle just on JS side
teardown_managed_proxy(this, this.gc_handle, /*skipManaged: */ true);
// order of operations with teardown_managed_proxy matters
Expand Down
1 change: 1 addition & 0 deletions src/mono/browser/runtime/gc-handles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ function _js_owned_object_finalized(gc_handle: GCHandle): void {
// We're shutting down, so don't bother doing anything else.
return;
}
mono_log_warn("_js_owned_object_finalized " + gc_handle);
teardown_managed_proxy(null, gc_handle);
}

Expand Down
4 changes: 2 additions & 2 deletions src/mono/browser/runtime/loader/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import WasmEnableThreads from "consts:wasmEnableThreads";

import { MainThreadingMode, type DotnetModuleInternal, type MonoConfigInternal, JSThreadBlockingMode, JSThreadInteropMode } from "../types/internal";
import type { DotnetModuleConfig, MonoConfig, ResourceGroups, ResourceList } from "../types";
import { ENVIRONMENT_IS_WEB, exportedRuntimeAPI, loaderHelpers, runtimeHelpers } from "./globals";
import { exportedRuntimeAPI, loaderHelpers, runtimeHelpers } from "./globals";
import { mono_log_error, mono_log_debug } from "./logging";
import { importLibraryInitializers, invokeLibraryInitializers } from "./libraryInitializers";
import { mono_exit } from "./exit";
Expand Down Expand Up @@ -178,7 +178,7 @@ export function normalizeConfig() {
}
}

loaderHelpers.assertAfterExit = config.assertAfterExit = config.assertAfterExit || !ENVIRONMENT_IS_WEB;
loaderHelpers.assertAfterExit = true;

if (config.debugLevel === undefined && BuildConfiguration === "Debug") {
config.debugLevel = -1;
Expand Down
2 changes: 1 addition & 1 deletion src/mono/browser/runtime/loader/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export function setLoaderGlobals(

maxParallelDownloads: 16,
enableDownloadRetry: true,
assertAfterExit: !ENVIRONMENT_IS_WEB,
assertAfterExit: true,

_loaded_files: [],
loadedFiles: [],
Expand Down
2 changes: 2 additions & 0 deletions src/mono/browser/runtime/marshal-to-cs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { JSMarshalerArgument, JSMarshalerArguments, JSMarshalerType, MarshalerTo
import { TypedArray } from "./types/emscripten";
import { addUnsettledPromise } from "./pthreads";
import { gc_locked } from "./gc-lock";
import { mono_log_warn } from "./logging";

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

Expand Down Expand Up @@ -332,6 +333,7 @@ function _marshal_task_to_cs(arg: JSMarshalerArgument, value: Promise<any>, _?:
set_arg_type(arg, MarshalerType.Task);
}

mono_log_warn("_marshal_task_to_cs handleIsPreallocated:" + handleIsPreallocated + " " + gc_handle + " at " + promiseHolderPtr);
const holder = new PromiseHolder(value, gc_handle, promiseHolderPtr, res_converter);
setup_managed_proxy(holder, gc_handle);

Expand Down
2 changes: 2 additions & 0 deletions src/mono/browser/runtime/marshal-to-js.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { get_marshaler_to_cs_by_type, jsinteropDoc, marshal_exception_to_cs } fr
import { localHeapViewF64, localHeapViewI32, localHeapViewU8 } from "./memory";
import { call_delegate } from "./managed-exports";
import { gc_locked } from "./gc-lock";
import { mono_log_warn } from "./logging";

export function initialize_marshalers_to_js(): void {
if (cs_to_js_marshalers.size == 0) {
Expand Down Expand Up @@ -207,6 +208,7 @@ function _marshal_delegate_to_js(arg: JSMarshalerArgument, _?: MarshalerType, re
result.dispose = () => {
if (!result.isDisposed) {
result.isDisposed = true;
mono_log_warn("_marshal_delegate_to_js " + gc_handle);
teardown_managed_proxy(result, gc_handle);
}
};
Expand Down
4 changes: 4 additions & 0 deletions src/mono/browser/runtime/marshal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { GCHandle, JSHandle, MonoObject, MonoString, GCHandleNull, JSMarshalerAr
import { TypedArray, VoidPtr } from "./types/emscripten";
import { utf16ToString } from "./strings";
import { get_managed_stack_trace } from "./managed-exports";
import { mono_log_warn } from "./logging";

export const cs_to_js_marshalers = new Map<MarshalerType, MarshalerToJs>();
export const js_to_cs_marshalers = new Map<MarshalerType, MarshalerToCs>();
Expand Down Expand Up @@ -373,6 +374,7 @@ export interface IDisposable {

export class ManagedObject implements IDisposable {
dispose(): void {
mono_log_warn("ManagedObject.dispose " + (<any>this)[js_owned_gc_handle_symbol]);
teardown_managed_proxy(this, GCHandleNull);
}

Expand Down Expand Up @@ -428,6 +430,7 @@ export class ManagedError extends Error implements IDisposable {
}

dispose(): void {
mono_log_warn("ManagedError.dispose " + (<any>this)[js_owned_gc_handle_symbol]);
teardown_managed_proxy(this, GCHandleNull);
}

Expand Down Expand Up @@ -556,6 +559,7 @@ export class ArraySegment extends MemoryView {
}

dispose(): void {
mono_log_warn("ArraySegment.dispose " + (<any>this)[js_owned_gc_handle_symbol]);
teardown_managed_proxy(this, GCHandleNull);
}

Expand Down
2 changes: 1 addition & 1 deletion src/mono/browser/runtime/memory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ export function compareExchangeI32(offset: MemOffset, value: number, expected: n
}
return actual;
}
return globalThis.Atomics.compareExchange(localHeapViewI32(), <any>offset >>> 2, value, expected);
return globalThis.Atomics.compareExchange(localHeapViewI32(), <any>offset >>> 2, expected, value);
}

export function storeI32(offset: MemOffset, value: number): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,19 +78,23 @@
private async Task SignalRPassMessages() =>
await Task.Run(async () =>
{
Helper.TestOutputWriteLine($"SignalRPassMessages on CurrentManagedThreadId={Environment.CurrentManagedThreadId}");
await _hubConnection.SendAsync( "SendMessage", message, Environment.CurrentManagedThreadId);
Helper.TestOutputWriteLine($"SignalRPassMessages was sent by CurrentManagedThreadId={Environment.CurrentManagedThreadId}");
});

private async Task SendExitSignal()
{
Helper.TestOutputWriteLine($"SendExitSignal on CurrentManagedThreadId={Environment.CurrentManagedThreadId}");
await DisposeHubConnection();
// exit the client
await JSRuntime.InvokeVoidAsync("eval", "import('./dotnet.js').then(module => { module.dotnet; module.exit(0); });");
Helper.TestOutputWriteLine($"SendExitSignal done on CurrentManagedThreadId={Environment.CurrentManagedThreadId}");
}

private async Task DisposeHubConnection()
{
Helper.TestOutputWriteLine($"DisposeHubConnection on CurrentManagedThreadId={Environment.CurrentManagedThreadId}");
if (_hubConnection != null)
{
_hubConnection.Remove("ReceiveMessage");
Expand Down
Loading