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] fix various issues and enable System.Runtime.InteropServices.JavaScript.Tests #99000

Merged
merged 5 commits into from
Mar 11, 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
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,6 @@ private void Dispose(bool disposing)
{
Environment.FailFast($"JSProxyContext must be disposed on the thread which owns it, ManagedThreadId: {Environment.CurrentManagedThreadId}. {Environment.NewLine} {Environment.StackTrace}");
}
((GCHandle)ContextHandle).Free();
#endif

List<WeakReference<JSObject>> copy = new(ThreadCsOwnedObjects.Values);
Expand All @@ -531,6 +530,7 @@ private void Dispose(bool disposing)

#if FEATURE_WASM_MANAGED_THREADS
Interop.Runtime.UninstallWebWorkerInterop();
((GCHandle)ContextHandle).Free();
#endif

foreach (var gch in ThreadJsOwnedObjects.Values)
Expand All @@ -544,6 +544,7 @@ private void Dispose(bool disposing)
{
holder.Callback!.Invoke(null);
}
((GCHandle)holder.GCHandle).Free();
}

ThreadCsOwnedObjects.Clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,10 @@ private void Pump()
}
try
{
if (SynchronizationContext.Current == null)
{
SetSynchronizationContext(this);
}
while (Queue.Reader.TryRead(out var item))
{
try
Expand Down
7 changes: 1 addition & 6 deletions src/libraries/tests.proj
Original file line number Diff line number Diff line change
Expand Up @@ -398,9 +398,6 @@
<!-- Issue: https://github.com/dotnet/runtime/issues/95795 -->
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Runtime\tests\System.Globalization.Tests\Hybrid\System.Globalization.Hybrid.WASM.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Runtime\tests\System.Globalization.Calendars.Tests\Hybrid\System.Globalization.Calendars.Hybrid.WASM.Tests.csproj" />
<!-- Issue: https://github.com/dotnet/runtime/issues/98406 -->
<!-- Issue: https://github.com/dotnet/runtime/issues/98101 -->
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Runtime.InteropServices.JavaScript\tests\System.Runtime.InteropServices.JavaScript.UnitTests\System.Runtime.InteropServices.JavaScript.Tests.csproj" />
</ItemGroup>

<ItemGroup Condition="'$(TargetOS)' == 'browser' and '$(WasmEnableThreads)' != 'true' and '$(RunDisabledWasmTests)' != 'true'">
Expand Down Expand Up @@ -616,9 +613,7 @@
<!-- Don't want the default smoke tests - just verify that threading works -->
<SmokeTestProject Remove="@(SmokeTestProject)" />
<SmokeTestProject Include="$(MonoProjectRoot)sample\wasm\browser-threads\Wasm.Browser.Threads.Sample.csproj" />
<!-- Issue: https://github.com/dotnet/runtime/issues/98406 -->
<!-- Issue: https://github.com/dotnet/runtime/issues/98101 -->
<!-- <SmokeTestProject Include="$(MSBuildThisFileDirectory)System.Runtime.InteropServices.JavaScript\tests\System.Runtime.InteropServices.JavaScript.UnitTests\System.Runtime.InteropServices.JavaScript.Tests.csproj" /> -->
<SmokeTestProject Include="$(MSBuildThisFileDirectory)System.Runtime.InteropServices.JavaScript\tests\System.Runtime.InteropServices.JavaScript.UnitTests\System.Runtime.InteropServices.JavaScript.Tests.csproj" />
<SmokeTestProject Include="$(MSBuildThisFileDirectory)System.Net.WebSockets.Client\tests\System.Net.WebSockets.Client.Tests.csproj" />
<SmokeTestProject Include="$(MSBuildThisFileDirectory)System.Net.Http\tests\FunctionalTests\System.Net.Http.Functional.Tests.csproj" />
</ItemGroup>
Expand Down
12 changes: 8 additions & 4 deletions src/mono/browser/runtime/cancelable-promise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,12 @@ export class PromiseHolder extends ManagedObject {
}

resolve(data: any) {
mono_assert(!this.isResolved, "resolve could be called only once");
mono_assert(!this.isDisposed, "resolve is already disposed.");
if (!loaderHelpers.is_runtime_running()) {
mono_log_debug("This promise resolution can't be propagated to managed code, mono runtime already exited.");
return;
}
mono_assert(!this.isResolved, "resolve could be called only once");
mono_assert(!this.isDisposed, "resolve is already disposed.");
if (WasmEnableThreads && !this.setIsResolving()) {
// we know that cancelation is in flight
// because we need to keep the GCHandle alive until until the cancelation arrives
Expand All @@ -102,12 +102,12 @@ export class PromiseHolder extends ManagedObject {
}

reject(reason: any) {
mono_assert(!this.isResolved, "reject could be called only once");
mono_assert(!this.isDisposed, "resolve is already disposed.");
if (!loaderHelpers.is_runtime_running()) {
mono_log_debug("This promise rejection can't be propagated to managed code, mono runtime already exited.");
return;
}
mono_assert(!this.isResolved, "reject could be called only once");
mono_assert(!this.isDisposed, "resolve is already disposed.");
const isCancelation = reason && reason[promise_holder_symbol] === this;
if (WasmEnableThreads && !isCancelation && !this.setIsResolving()) {
// we know that cancelation is in flight
Expand All @@ -127,6 +127,10 @@ export class PromiseHolder extends ManagedObject {
}

cancel() {
if (!loaderHelpers.is_runtime_running()) {
mono_log_debug("This promise cancelation can't be propagated to managed code, mono runtime already exited.");
return;
}
mono_assert(!this.isResolved, "cancel could be called only once");
mono_assert(!this.isDisposed, "resolve is already disposed.");

Expand Down
5 changes: 4 additions & 1 deletion src/mono/browser/runtime/gc-handles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export function teardown_managed_proxy(owner: any, gc_handle: GCHandle, skipMana
}
}
if (gc_handle !== GCHandleNull && _js_owned_object_table.delete(gc_handle) && !skipManaged) {
if (loaderHelpers.is_runtime_running()) {
if (loaderHelpers.is_runtime_running() && !force_dispose_proxies_in_progress) {
release_js_owned_object_by_gc_handle(gc_handle);
}
}
Expand Down Expand Up @@ -204,11 +204,14 @@ export function assertNoProxies(): void {
mono_assert(js_import_wrapper_by_fn_handle.length === 1, "There should be no imports on this thread.");
}

let force_dispose_proxies_in_progress = false;

// when we arrive here from UninstallWebWorkerInterop, the C# will unregister the handles too.
// when called from elsewhere, C# side could be unbalanced!!
export function forceDisposeProxies(disposeMethods: boolean, verbose: boolean): void {
let keepSomeCsAlive = false;
let keepSomeJsAlive = false;
force_dispose_proxies_in_progress = true;

let doneImports = 0;
let doneExports = 0;
Expand Down
17 changes: 14 additions & 3 deletions src/mono/browser/runtime/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ function commonAsserts(controller: HttpController) {
mono_assert(controller, "expected controller");
}

let http_wasm_supports_streaming_request_cached: boolean | undefined;
export function http_wasm_supports_streaming_request(): boolean {
if (http_wasm_supports_streaming_request_cached !== undefined) {
return http_wasm_supports_streaming_request_cached;
}
// Detecting streaming request support works like this:
// If the browser doesn't support a particular body type, it calls toString() on the object and uses the result as the body.
// So, if the browser doesn't support request streams, the request body becomes the string "[object ReadableStream]".
Expand All @@ -43,13 +47,20 @@ export function http_wasm_supports_streaming_request(): boolean {
return "half";
},
} as RequestInit /* https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1483 */).headers.has("Content-Type");
return duplexAccessed && !hasContentType;
http_wasm_supports_streaming_request_cached = duplexAccessed && !hasContentType;
} else {
http_wasm_supports_streaming_request_cached = false;
}
return false;
return http_wasm_supports_streaming_request_cached;
}

let http_wasm_supports_streaming_response_cached: boolean | undefined;
export function http_wasm_supports_streaming_response(): boolean {
return typeof Response !== "undefined" && "body" in Response.prototype && typeof ReadableStream === "function";
if (http_wasm_supports_streaming_response_cached !== undefined) {
return http_wasm_supports_streaming_response_cached;
}
http_wasm_supports_streaming_response_cached = typeof Response !== "undefined" && "body" in Response.prototype && typeof ReadableStream === "function";
return http_wasm_supports_streaming_response_cached;
}

export function http_wasm_create_controller(): HttpController {
Expand Down
2 changes: 1 addition & 1 deletion src/mono/browser/runtime/marshal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ export function set_arg_element_type(arg: JSMarshalerArgument, type: MarshalerTy

export function get_arg_bool(arg: JSMarshalerArgument): boolean {
mono_assert(arg, "Null arg");
return getB32(<any>arg);
return !!getU8(<any>arg);
}

export function get_arg_u8(arg: JSMarshalerArgument): number {
Expand Down
Loading