-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
[wasm-mt] Add MessageChannel between browser thread and new pthreads #70908
Conversation
Tagging subscribers to 'arch-wasm': @lewing Issue DetailsAdd a mechanism for creating a communication channel between the browser thread and new pthreads (running in webworkers - note, Emscripten may recycle workers after a pthread exits). This is done by adding our own event listener to the webworker (in the main thread) and to globalThis (in the worker). This conflicts with emscripten's message handlers (although it's considered a bug by Emscripten upstream that their event handler doesn't ignore unrecognized messages). The downside of the current approach is that we need to run some async work on the main thread (because otherwise there's no good way to get notified when Emscripten spins up a new worker - the mechanism isn't extensible). So if the main thread isn't servicing Emscripten's async work queue, we might block. Once we have our message handlers in place, the rest is straightforward, the worker creates a MessageChannel and transfers one of the ports to the browser thread. Right now the messagePort is just dropped on the floor, but the right thing is to keep a dictionary of them in the main thread. This isn't done yet. With the browser-to-pthread channel established, we can build up cross-thread channels by asking the main thread to transfer ports on our behalf. This part isn't done yet, either.
|
This comment was marked as resolved.
This comment was marked as resolved.
6705c84
to
662e0f6
Compare
549636a
to
b7d51f6
Compare
989c721
to
a87e135
Compare
was used to validate that a pthread message channel is working. Not needed in this sample, because the internal EventPipe sampling thread is good enough as proof
Use it to call mono_wasm_pthread_on_pthread_created Rename the previous callback to mono_wasm_pthread_on_pthread_attached - it gets called but it's unused. This is enough to get the diagnostic sever worker started up and pinging.
Cleaned up a little bit: I now have a "on created" and "on attached" calls - the first is called from Emscripten's |
could we perhaps have something like pattern EventTarget named And subscribers would call |
done. subsystems in the runtime can now do: import { currentWorkerThreadEvents, dotnetPthreadCreated, WorkerThreadEvent } from './pthreads/worker';
currentWorkerThreadEvents.addEventListener(dotnetPthreadCreated, (ev: WorkerThreadEvent) => {
/* do stuff with ev.pthread_ptr */
}); |
this lets pthread lifecycle event handlers post messages and setup listeners on the message port back to the main browser thread. Also update the README to describe the current design
Trimming tests failing:
|
Yea Im' working on it. There's two issues:
|
LGTM |
rollup doesn't understand fallthru. In the following (which is what `mono_assert` ammounts to) it retains `C`: ``` if (condition) throw new Error (...); // fallthru return new C(); ``` Solution is to use an if-then-else ``` if (condition) throw new Error (...); else return new C(); // C is not retained if 'condition' is false ```
Update filed an issue about it rollup/rollup#4542 weird, apparently rollup doesn't understand that if import condition from "consts:condition";
class C {
constructor () {}
...
}
export function makeC () {
if (!condition)
throw new Error ("condition is false");
// fallthru
return new C(); // rollup incorrectly retains C
} It rewrites the function to always throw, but still keeps the definition of class C {
constructor() { }
...
}
export function makeC() {
throw new Error ("condition is false");
} However this works: import condition from "consts:condition";
class C {
constructor () {}
...
}
export function makeC () {
if (!condition)
throw new Error ("condition is false");
else
return new C(); // rollup doesn't retain C
} |
Cannot read property 'loc' of undefined See microsoft/vscode-eslint#1149 and a proposed workaround in eslint/eslint#14538 (comment)
v8 shell doesn't have |
Add a mechanism for creating a communication channel between the browser thread and new pthreads (running in webworkers - note, Emscripten may recycle workers after a pthread exits).
This is done by adding our own event listener to the webworker (in the main thread) and to globalThis (in the worker). This conflicts with emscripten's message handlers (although it's considered a bug by Emscripten upstream that their event handler doesn't ignore unrecognized messages).
One potential problem here is that for any communication to happen, the worker must service its event loop. If it's just busy running a loop in wasm, it might never handle the messages. On the other hand, posting messages back to main should work.
Once we have our message handlers in place, the rest is straightforward, the worker creates a MessageChannel and transfers one of the ports to the browser thread.
With the browser-to-pthread channel established, we can build up cross-thread channels by asking the main thread to transfer ports on our behalf. This part isn't done yet.