diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoHandler.cs b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoHandler.cs index 6888c57e11285b..667e99c29dc398 100644 --- a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoHandler.cs +++ b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoHandler.cs @@ -7,6 +7,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; namespace NetCoreServer { @@ -30,6 +31,24 @@ public static async Task InvokeAsync(HttpContext context) byte[] bytes = Encoding.UTF8.GetBytes(echoJson); + var delay = 0; + if (context.Request.QueryString.HasValue) + { + if (context.Request.QueryString.Value.Contains("delay1sec")) + { + delay = 1000; + } + else if (context.Request.QueryString.Value.Contains("delay10sec")) + { + delay = 10000; + } + } + + if (delay > 0) + { + context.Features.Get().DisableBuffering(); + } + // Compute MD5 hash so that clients can verify the received data. using (MD5 md5 = MD5.Create()) { @@ -41,20 +60,19 @@ public static async Task InvokeAsync(HttpContext context) context.Response.ContentLength = bytes.Length; } - if (context.Request.QueryString.HasValue && context.Request.QueryString.Value.Contains("delay10sec")) + if (delay > 0) { await context.Response.StartAsync(CancellationToken.None); + await context.Response.Body.WriteAsync(bytes, 0, 10); + await context.Response.Body.FlushAsync(); + await Task.Delay(delay); + await context.Response.Body.WriteAsync(bytes, 10, bytes.Length-10); await context.Response.Body.FlushAsync(); - - await Task.Delay(10000); } - else if (context.Request.QueryString.HasValue && context.Request.QueryString.Value.Contains("delay1sec")) + else { - await context.Response.StartAsync(CancellationToken.None); - await Task.Delay(1000); + await context.Response.Body.WriteAsync(bytes, 0, bytes.Length); } - - await context.Response.Body.WriteAsync(bytes, 0, bytes.Length); } } } diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptImports.Generated.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptImports.Generated.cs index 7d734d8babe780..10f737f5a9c9ce 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptImports.Generated.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptImports.Generated.cs @@ -43,7 +43,6 @@ internal static unsafe partial class JavaScriptImports [JSImport("INTERNAL.get_dotnet_instance")] public static partial JSObject GetDotnetInstance(); [JSImport("INTERNAL.dynamic_import")] - // TODO: the continuation should be running on deputy or TP in MT public static partial Task DynamicImport(string moduleName, string moduleUrl); [JSImport("INTERNAL.mono_wasm_bind_cs_function")] @@ -51,7 +50,6 @@ internal static unsafe partial class JavaScriptImports #if FEATURE_WASM_MANAGED_THREADS [JSImport("INTERNAL.thread_available")] - // TODO: the continuation should be running on deputy or TP in MT public static partial Task ThreadAvailable(); #endif diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/WebWorkerTest.Http.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/WebWorkerTest.Http.cs index 53d45b99678e90..16ef9f72cf5573 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/WebWorkerTest.Http.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/WebWorkerTest.Http.cs @@ -81,23 +81,11 @@ await HttpClient_ActionInDifferentThread(url, executor1, executor2, async (HttpR await Assert.ThrowsAsync(async () => { CancellationTokenSource cts = new CancellationTokenSource(); - try - { - var promise = response.Content.ReadAsStringAsync(cts.Token); - Console.WriteLine("HttpClient_CancelInDifferentThread: ManagedThreadId: " + Environment.CurrentManagedThreadId + " NativeThreadId: " + WebWorkerTestHelper.NativeThreadId); - cts.Cancel(); - await promise; - } - catch (TaskCanceledException ex) - { - Console.WriteLine("HttpClient_CancelInDifferentThread: TaskCanceledException is thrown with message: " + ex.ToString()); - throw; - } - catch (OperationCanceledException ex) - { - Console.WriteLine("HttpClient_CancelInDifferentThread: OperationCanceledException is thrown with message: " + ex.ToString()); - throw; - } + var promise = response.Content.ReadAsStringAsync(cts.Token); + Console.WriteLine("HttpClient_CancelInDifferentThread: ManagedThreadId: " + Environment.CurrentManagedThreadId + " NativeThreadId: " + WebWorkerTestHelper.NativeThreadId); + cts.Cancel(); + var res = await promise; + throw new Exception("This should be unreachable: " + res); }); }); } diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/WebWorkerTestBase.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/WebWorkerTestBase.cs index 3fb53d484def06..1df4c61e6bcbc6 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/WebWorkerTestBase.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/WebWorkerTestBase.cs @@ -135,12 +135,15 @@ async Task ActionsInDifferentThreads2() { throw; } - Console.WriteLine("ActionsInDifferentThreads failed with: \n" + ex); if (!e1Done || !e2Done) { - Console.WriteLine("ActionsInDifferentThreads canceling!"); + Console.WriteLine("ActionsInDifferentThreads canceling because of unexpected fail: \n" + ex); cts.Cancel(); } + else + { + Console.WriteLine("ActionsInDifferentThreads failed with: \n" + ex); + } throw; } } diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/WebWorkerTestHelper.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/WebWorkerTestHelper.cs index 1fc94b83adba99..9a1856780d5d5b 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/WebWorkerTestHelper.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/WebWorkerTestHelper.cs @@ -48,7 +48,7 @@ public partial class WebWorkerTestHelper public static NamedCall CurrentCallback; public static CancellationToken CurrentCancellationToken = CancellationToken.None; public static Exception? LastException = null; - + [JSExport] public static void CallCurrentCallback() { @@ -333,7 +333,7 @@ public static Task RunOnNewThread(Func job, CancellationToken cancellation } catch (Exception ex) { - if(ex is AggregateException agg) + if (ex is AggregateException agg) { tcs.TrySetException(agg.InnerException); } diff --git a/src/mono/browser/runtime/cancelable-promise.ts b/src/mono/browser/runtime/cancelable-promise.ts index cf0b048a2c60cd..362ad3c5de30f5 100644 --- a/src/mono/browser/runtime/cancelable-promise.ts +++ b/src/mono/browser/runtime/cancelable-promise.ts @@ -56,7 +56,7 @@ export class PromiseHolder extends ManagedObject { public isPosted = false; public isPostponed = false; public data: any = null; - public reason: any = null; + public reason: any = undefined; public constructor(public promise: Promise, private gc_handle: GCHandle, private promiseHolderPtr: number, // could be null for GCV_handle diff --git a/src/mono/browser/runtime/http.ts b/src/mono/browser/runtime/http.ts index 0e45e2ec819752..6e4f66d0e214a8 100644 --- a/src/mono/browser/runtime/http.ts +++ b/src/mono/browser/runtime/http.ts @@ -87,6 +87,7 @@ export function http_wasm_abort_request(controller: HttpController): void { export function http_wasm_abort_response(controller: HttpController): void { if (BuildConfiguration === "Debug") commonAsserts(controller); try { + controller.isAborted = true; if (controller.streamReader) { controller.streamReader.cancel().catch((err) => { if (err && err.name !== "AbortError") { @@ -251,6 +252,9 @@ export function http_wasm_get_streamed_response_bytes(controller: HttpController controller.currentBufferOffset = 0; } if (controller.currentStreamReaderChunk.done) { + if (controller.isAborted) { + throw new Error("OperationCanceledException"); + } return 0; } @@ -271,6 +275,7 @@ export function http_wasm_get_streamed_response_bytes(controller: HttpController interface HttpController { abortController: AbortController + isAborted?: boolean // streaming request streamReader?: ReadableStreamDefaultReader diff --git a/src/mono/mono/utils/mono-threads-wasm.c b/src/mono/mono/utils/mono-threads-wasm.c index cfd411c712c385..97ac4e1e2cea25 100644 --- a/src/mono/mono/utils/mono-threads-wasm.c +++ b/src/mono/mono/utils/mono-threads-wasm.c @@ -629,7 +629,6 @@ mono_wasm_register_ui_thread (void) MONO_ENTER_GC_SAFE_UNBALANCED; } -// TODO ideally we should not need to have UI thread registered as managed EMSCRIPTEN_KEEPALIVE void mono_wasm_register_io_thread (void) {