TL;DR
How do I add a message handler to Emscripten's generated worker output?
I am porting my C++ terminal application to WASM using Emscripten so I can run it in a browser. The application is blocking and uses a thread internally, so I build with PROXY_TO_PTHREAD and USE_PTHREADS which results in a web-worker being launched to run main and another for the application thread (this is how Emscripten emulates pthreads in the browser).
The application can require input data, and for that I need to get text from a HTML element into my worker to feed the application's stdin. Using the Worker API I can use postMessage to send data to my worker, but I can't figure out how to add a message handler in the worker!
There is a Module.onCustomMessage property which can do this, but it is only valid when built with PROXY_TO_WORKER - which isn't allowed when using pthreads.
Another approach I tried, which is very hacky, is to try to wrap the onmessage function in the worker:
EM_JS(int, malbolge_input, (char* buffer, int maxlen), {
return Asyncify.handleAsync(async () => {
if (typeof Module.malbolgeConfigured == "undefined") {
...
let standard_handlers = self.onmessage;
self.onmessage = function(e) {
console.log("\tWorker handler: " + e.data.cmd);
if (e.data.cmd === "input_text") {
Module.malbolgeInputQueue.push(e.data.input_text);
Module.malbolgeInputNotify();
} else {
standard_handlers(e);
}
};
}
...
Unfortunately only the original function is ever called, never the wrapper, and I don't know why.
Another alternative is to patch the generated *_worker.js to manually add a handler, but it is a very brittle solution as it will be very dependent on the version of Emscripten being used.