Emscripten: пользовательский обработчик сообщений при использовании pthreads

#javascript #c #pthreads #web-worker #emscripten

#javascript #c #pthreads #веб-работник #emscripten

Вопрос:

TL;DR
Как мне добавить обработчик сообщений в сгенерированный рабочий вывод Emscripten?


Я переношу свое терминальное приложение C на WASM с помощью Emscripten, чтобы я мог запускать его в браузере. Приложение блокируется и использует поток внутри, поэтому я создаю с помощью PROXY_TO_PTHREAD и USE_PTHREADS , что приводит к запуску web-worker для запуска main и другого для потока приложения (именно так Emscripten эмулирует pthreads в браузере).

Приложению могут потребоваться входные данные, и для этого мне нужно получить текст из HTML-элемента в мой worker, чтобы передать его приложению stdin . Используя Worker API, я могу использовать postMessage для отправки данных моему worker, но я не могу понять, как добавить обработчик сообщений в worker!

Существует Module.onCustomMessage свойство, которое может это сделать, но оно допустимо только при создании с помощью PROXY_TO_WORKER , что недопустимо при использовании pthreads.

Другой подход, который я пробовал, который является очень хакерским, заключается в попытке обернуть функцию onmessage в 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);
                }
            };
        }
    ...
  

К сожалению, когда-либо вызывается только исходная функция, никогда оболочка, и я не знаю почему.

Другой альтернативой является исправление сгенерированного *_worker.js , чтобы вручную добавить обработчик, но это очень хрупкое решение, поскольку оно будет сильно зависеть от используемой версии Emscripten.