Skip to content
Draft
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
4 changes: 2 additions & 2 deletions src/mono/browser/runtime/cwraps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const fn_signatures: SigLine[] = [
[true, "mono_wasm_parse_runtime_options", null, ["number", "number"]],
[true, "mono_wasm_strdup", "number", ["string"]],
[true, "mono_background_exec", null, []],
[true, "mono_wasm_ds_exec", null, []],
[true, "SystemJS_ExecuteDiagnosticServerCallback", null, []],
[true, "mono_wasm_execute_timer", null, []],
[true, "wasm_load_icu_data", "number", ["number"]],
[false, "mono_wasm_add_assembly", "number", ["string", "number", "number"]],
Expand Down Expand Up @@ -168,7 +168,7 @@ export interface t_Cwraps {
mono_wasm_strdup(value: string): number;
mono_wasm_parse_runtime_options(length: number, argv: VoidPtr): void;
mono_background_exec(): void;
mono_wasm_ds_exec(): void;
SystemJS_ExecuteDiagnosticServerCallback(): void;
mono_wasm_execute_timer(): void;
wasm_load_icu_data(offset: VoidPtr): number;
mono_wasm_add_assembly(name: string, data: VoidPtr, size: number): number;
Expand Down
2 changes: 1 addition & 1 deletion src/mono/browser/runtime/diagnostics/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function diagnosticServerEventLoop () {
if (loaderHelpers.is_runtime_running()) {
try {
runtimeHelpers.mono_background_exec();// give GC chance to run
runtimeHelpers.mono_wasm_ds_exec();
runtimeHelpers.SystemJS_ExecuteDiagnosticServerCallback();
scheduleDiagnosticServerEventLoop(100);
} catch (ex) {
loaderHelpers.mono_exit(1, ex);
Expand Down
4 changes: 2 additions & 2 deletions src/mono/browser/runtime/diagnostics/diagnostics-ws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class DiagnosticConnectionWS extends DiagnosticConnectionBase implements IDiagno
};
ws.addEventListener("open", () => {
for (const data of this.messagesToSend) {
ws.send(data);
ws.send(data as any);
}
this.messagesToSend = [];
diagnosticServerEventLoop();
Expand All @@ -49,7 +49,7 @@ class DiagnosticConnectionWS extends DiagnosticConnectionBase implements IDiagno
return super.store(message);
}

this.ws!.send(message);
this.ws!.send(message as any);

return message.length;
}
Expand Down
2 changes: 1 addition & 1 deletion src/mono/browser/runtime/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ function initializeExports (globalObjects: GlobalObjects): RuntimeAPI {
utf8ToString,
SystemJS_GetCurrentProcessId,
mono_background_exec: () => tcwraps.mono_background_exec(),
mono_wasm_ds_exec: () => tcwraps.mono_wasm_ds_exec(),
SystemJS_ExecuteDiagnosticServerCallback: () => tcwraps.SystemJS_ExecuteDiagnosticServerCallback(),
};
if (WasmEnableThreads) {
rh.dumpThreads = mono_wasm_dump_threads;
Expand Down
2 changes: 1 addition & 1 deletion src/mono/browser/runtime/types/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ export type RuntimeHelpers = {
mono_wasm_print_thread_dump: () => void,
utf8ToString: (ptr: CharPtr) => string,
mono_background_exec: () => void,
mono_wasm_ds_exec: () => void,
SystemJS_ExecuteDiagnosticServerCallback: () => void,
SystemJS_GetCurrentProcessId: () => number,
}

Expand Down
4 changes: 2 additions & 2 deletions src/mono/mono/eventpipe/ep-rt-mono.h
Original file line number Diff line number Diff line change
Expand Up @@ -1011,7 +1011,7 @@ ep_rt_queue_job (
// see if it's done or needs to be scheduled again
if (!done) {
// self schedule again
mono_schedule_ds_job (cb, params);
SystemJS_DiagnosticServerQueueJob (cb, params);
}

return true;
Expand Down Expand Up @@ -1045,7 +1045,7 @@ ep_rt_thread_sleep (uint64_t ns)
g_usleep ((gulong)(ns / 1000));
MONO_EXIT_GC_SAFE;
}
#endif
#endif // PERFTRACING_DISABLE_THREADS
}

static
Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/mini/mini-wasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ G_BEGIN_DECLS
#ifdef DISABLE_THREADS
EMSCRIPTEN_KEEPALIVE void mono_wasm_execute_timer (void);
EMSCRIPTEN_KEEPALIVE void mono_background_exec (void);
EMSCRIPTEN_KEEPALIVE void mono_wasm_ds_exec (void);
EMSCRIPTEN_KEEPALIVE void SystemJS_ExecuteDiagnosticServerCallback (void);
extern void SystemJS_ScheduleTimerImpl (int shortestDueTimeMs);
#else
extern void SystemJS_ScheduleSynchronizationContext(MonoNativeThreadId target_thread);
Expand Down
10 changes: 5 additions & 5 deletions src/mono/mono/utils/mono-threads-wasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ typedef struct {
} DsJobRegistration;

void
mono_schedule_ds_job (ds_job_cb cb, void* data)
SystemJS_DiagnosticServerQueueJob (ds_job_cb cb, void* data)
{
g_assert (cb);
DsJobRegistration* reg = g_new0 (DsJobRegistration, 1);
Expand Down Expand Up @@ -372,7 +372,7 @@ mono_background_exec (void)

G_EXTERN_C
EMSCRIPTEN_KEEPALIVE void
mono_wasm_ds_exec (void)
SystemJS_ExecuteDiagnosticServerCallback (void)
{
MONO_ENTER_GC_UNSAFE;
GSList *j1 = jobs_ds, *cur1;
Expand All @@ -381,13 +381,13 @@ mono_wasm_ds_exec (void)
for (cur1 = j1; cur1; cur1 = cur1->next) {
DsJobRegistration* reg = (DsJobRegistration*)cur1->data;
g_assert (reg->cb);
THREADS_DEBUG ("mono_wasm_ds_exec running job %p \n", (gpointer)cb);
THREADS_DEBUG ("SystemJS_ExecuteDiagnosticServerCallback running job %p \n", (gpointer)reg->cb);
gsize done = reg->cb (reg->data);
if (done){
THREADS_DEBUG ("mono_wasm_ds_exec done job %p \n", (gpointer)cb);
THREADS_DEBUG ("SystemJS_ExecuteDiagnosticServerCallback done job %p \n", (gpointer)reg->cb);
g_free (reg);
} else {
THREADS_DEBUG ("mono_wasm_ds_exec scheduling job %p again \n", (gpointer)cb);
THREADS_DEBUG ("SystemJS_ExecuteDiagnosticServerCallback scheduling job %p again \n", (gpointer)reg->cb);
jobs_ds = g_slist_prepend (jobs_ds, (gpointer)reg);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/utils/mono-threads-wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ mono_wasm_atomic_wait_i32 (volatile int32_t *addr, int32_t expected, int32_t tim

#else /* DISABLE_THREADS */
void mono_background_exec (void);
void mono_wasm_ds_exec (void);
void SystemJS_ExecuteDiagnosticServerCallback (void);
#endif /* DISABLE_THREADS */

void
Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/utils/mono-threads.h
Original file line number Diff line number Diff line change
Expand Up @@ -848,7 +848,7 @@ typedef void (*background_job_cb)(void);
typedef gsize (*ds_job_cb)(void* data);
#ifdef DISABLE_THREADS
void SystemJS_ScheduleBackgroundJob (background_job_cb cb);
void mono_schedule_ds_job (ds_job_cb cb, void* data);
void SystemJS_DiagnosticServerQueueJob (ds_job_cb cb, void* data);
#else
void SystemJS_ScheduleSynchronizationContext(MonoNativeThreadId target_thread);
#endif // DISABLE_THREADS
Expand Down
9 changes: 9 additions & 0 deletions src/native/libs/Common/JavaScript/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,23 @@ set(ROLLUP_TS_SOURCES
"${CLR_SRC_NATIVE_DIR}/libs/Common/JavaScript/types/public-api.ts"
"${CLR_SRC_NATIVE_DIR}/libs/Common/JavaScript/types/v8.d.ts"

"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/diagnostics/client-commands.ts"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/diagnostics/common.ts"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/diagnostics/console-proxy.ts"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/diagnostics/cross-module.ts"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/diagnostics/diagnostic-server.ts"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/diagnostics/diagnostic-server-js.ts"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/diagnostics/diagnostic-server-ws.ts"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/diagnostics/dotnet-counters.ts"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/diagnostics/dotnet-cpu-profiler.ts"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/diagnostics/dotnet-gcdump.ts"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/diagnostics/exit.ts"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/diagnostics/index.ts"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/diagnostics/per-module.ts"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/diagnostics/symbolicate.ts"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/diagnostics/types.ts"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/native/crypto.ts"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/native/diagnostics.ts"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/native/globalization-locale.ts"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/native/index.ts"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/native/main.ts"
Expand Down
6 changes: 6 additions & 0 deletions src/native/libs/Common/JavaScript/cross-module/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ export function dotnetUpdateInternalsSubscriber() {
const interopLocal: NativeBrowserExports = {
getWasmMemory: table[0],
getWasmTable: table[1],
SystemJS_ScheduleDiagnosticServer: table[2],
};
Object.assign(interop, interopLocal);
}
Expand All @@ -186,6 +187,11 @@ export function dotnetUpdateInternalsSubscriber() {
const interopLocal: DiagnosticsExports = {
symbolicateStackTrace: table[0],
installNativeSymbols: table[1],
ds_rt_websocket_create: table[2],
ds_rt_websocket_send: table[3],
ds_rt_websocket_poll: table[4],
ds_rt_websocket_recv: table[5],
ds_rt_websocket_close: table[6],
};
Object.assign(interop, interopLocal);
}
Expand Down
2 changes: 1 addition & 1 deletion src/native/libs/Common/JavaScript/loader/dotnet.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@ type DiagnosticsAPIType = {
type DiagnosticCommandProviderV2 = {
keywords: [number, number];
logLevel: number;
provider_name: string;
providerName: string;
arguments: string | null;
};
type DiagnosticCommandOptions = {
Expand Down
3 changes: 3 additions & 0 deletions src/native/libs/Common/JavaScript/types/ems-ambient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export type EmsAmbientSymbolsType = EmscriptenModuleInternal & {
_SystemJS_ExecuteTimerCallback: () => void;
_SystemJS_ExecuteBackgroundJobCallback: () => void;
_SystemJS_ExecuteFinalizationCallback: () => void;
_SystemJS_ExecuteDiagnosticServerCallback: () => void;
_SystemJS_ScheduleDiagnosticServer: () => void;
_BrowserHost_CreateHostContract: () => VoidPtr;
_BrowserHost_InitializeDotnet: (propertiesCount: number, propertyKeys: CharPtrPtr, propertyValues: CharPtrPtr) => number;
_BrowserHost_ExecuteAssembly: (mainAssemblyNamePtr: number, argsLength: number, argsPtr: number) => number;
Expand All @@ -51,6 +53,7 @@ export type EmsAmbientSymbolsType = EmscriptenModuleInternal & {
lastScheduledTimerId?: number;
lastScheduledThreadPoolId?: number;
lastScheduledFinalizationId?: number;
lastScheduledDiagnosticServerId?: number;
cryptoWarnOnce?: boolean;
isAborting?: boolean;
isAsyncMain?: boolean;
Expand Down
14 changes: 14 additions & 0 deletions src/native/libs/Common/JavaScript/types/exchange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import type { cancelPromise } from "../../../System.Runtime.InteropServices.Java
import type { abortInteropTimers } from "../../../System.Runtime.InteropServices.JavaScript.Native/interop/scheduling";

import type { installNativeSymbols, symbolicateStackTrace } from "../../../System.Native.Browser/diagnostics/symbolicate";
import type { SystemJS_ScheduleDiagnosticServer } from "../../../System.Native.Browser/native";
import type { ds_rt_websocket_close, ds_rt_websocket_create, ds_rt_websocket_poll, ds_rt_websocket_recv, ds_rt_websocket_send } from "../../../System.Native.Browser/diagnostics/diagnostic-server";


type getWasmMemoryType = () => WebAssembly.Memory;
Expand Down Expand Up @@ -144,11 +146,13 @@ export type InteropJavaScriptExportsTable = [
export type NativeBrowserExports = {
getWasmMemory: getWasmMemoryType,
getWasmTable: getWasmTableType,
SystemJS_ScheduleDiagnosticServer: typeof SystemJS_ScheduleDiagnosticServer,
}

export type NativeBrowserExportsTable = [
getWasmMemoryType,
getWasmTableType,
typeof SystemJS_ScheduleDiagnosticServer,
]

export type BrowserUtilsExports = {
Expand Down Expand Up @@ -186,9 +190,19 @@ export type BrowserUtilsExportsTable = [
export type DiagnosticsExportsTable = [
typeof symbolicateStackTrace,
typeof installNativeSymbols,
typeof ds_rt_websocket_create,
typeof ds_rt_websocket_send,
typeof ds_rt_websocket_poll,
typeof ds_rt_websocket_recv,
typeof ds_rt_websocket_close,
]

export type DiagnosticsExports = {
symbolicateStackTrace: typeof symbolicateStackTrace,
installNativeSymbols: typeof installNativeSymbols,
ds_rt_websocket_create: typeof ds_rt_websocket_create,
ds_rt_websocket_send: typeof ds_rt_websocket_send,
ds_rt_websocket_poll: typeof ds_rt_websocket_poll,
ds_rt_websocket_recv: typeof ds_rt_websocket_recv,
ds_rt_websocket_close: typeof ds_rt_websocket_close,
}
2 changes: 1 addition & 1 deletion src/native/libs/Common/JavaScript/types/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,7 @@ export type DiagnosticsAPIType = {
export type DiagnosticCommandProviderV2 = {
keywords: [number, number];
logLevel: number;
provider_name: string;
providerName: string;
arguments: string | null;
};

Expand Down
2 changes: 1 addition & 1 deletion src/native/libs/System.Native.Browser/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
project(System.Native.Browser C)

set(BROWSER_SOURCES ${BROWSER_SOURCES} entrypoints.c)
set(BROWSER_SOURCES ${BROWSER_SOURCES} entrypoints.c diagnostic_server_jobs.c)

add_library(System.Native.Browser-Static
STATIC
Expand Down
57 changes: 57 additions & 0 deletions src/native/libs/System.Native.Browser/diagnostic_server_jobs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
#include <emscripten.h>

#include "diagnostic_server_jobs.h"

extern void SystemJS_ScheduleDiagnosticServer(void);

typedef struct DsJobNode {
ds_job_cb cb;
void *data;
struct DsJobNode *next;
} DsJobNode;

static DsJobNode *jobs;

void
SystemJS_DiagnosticServerQueueJob (ds_job_cb cb, void *data)
{
int wasEmpty = jobs == NULL;
assert (cb);
DsJobNode *node = (DsJobNode *)calloc (1, sizeof (DsJobNode));
if (!node) {
abort ();
}
node->cb = cb;
node->data = data;
node->next = jobs;
jobs = node;
if (wasEmpty) {
SystemJS_ScheduleDiagnosticServer ();
}
}

void
SystemJS_ExecuteDiagnosticServerCallback (void)
{
DsJobNode *list = jobs;
jobs = NULL;

while (list) {
DsJobNode *cur = list;
list = cur->next;
assert (cur->cb);
size_t done = cur->cb (cur->data);
if (done) {
free (cur);
} else {
cur->next = jobs;
jobs = cur;
}
}
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SystemJS_ExecuteDiagnosticServerCallback requeues jobs whose callback returns 0 (not done), but it never schedules another diagnostic-server tick afterwards. That means any incomplete job can stall indefinitely once the queue drains for this callback invocation. Consider calling SystemJS_ScheduleDiagnosticServer() again when jobs is non-null after processing (or scheduling each time a job is requeued).

Suggested change
}
}
if (jobs != NULL) {
SystemJS_ScheduleDiagnosticServer ();
}

Copilot uses AI. Check for mistakes.
}
12 changes: 12 additions & 0 deletions src/native/libs/System.Native.Browser/diagnostic_server_jobs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#pragma once

#include <stddef.h>

typedef size_t (*ds_job_cb)(void *data);

void SystemJS_DiagnosticServerQueueJob (ds_job_cb cb, void *data);
void SystemJS_ExecuteDiagnosticServerCallback (void);

Loading
Loading