Home > OS >  How to call worker thread function from main thread in Emscripten app?
How to call worker thread function from main thread in Emscripten app?

Time:10-15

I need to access local fonts of browser in WASM/Emscripten program. I am able to to that using queryLocalFonts API from here https://wicg.github.io/local-font-access/

Now accessing and processing local fonts is taking too long I need to do it in worker thread. Calling the API from worker thread is not supported yet so I am trying to call it from main thread then pass font data to worker thread for processing.

The problem is I can't figure out how to create and use worker thread in Emscripten app. I can create a worker thread in C using emscripten_malloc_wasm_worker from here https://emscripten.org/docs/api_reference/wasm_workers.html#example-code but I don't know how to call it from Javascript where I get font results from API call.

On the other hand when I try to create web worker in JavaScript using this call Module.LocalFontProcessingThread = new Worker("./ProcessLocalFonts.js") then I am not sure what should be the content of ProcessLocalFonts.js. If I put a placeholder like this

self.onmessage = function handleMessageFromMain(msg) {
  console.log("77777777777777777 message from main received in worker:", msg);
};

then I am getting error from Emscripten like self is not defined.

Do you know how that can be done? An example of calling worker thread from main thread in Emscripten app would be helpful.

CodePudding user response:

I have not used Emscripten's worker API. I can think of 2 other possibilities I can recommend. One is to load the wasm module in a worker OR use pthread and create a function to run in a separate worker internally through Emscripten's thread emulation.

Let's start with pthread support. You'd need the flags USE_PTHREADS=1 and PTHREAD_POOL_SIZE=4. Change pool size to what you might need. With this threadpool library, you can instantiate threads and submit functions to threads. How you manage, track and propagate completion/fail of threads is upto you. I usually pass in a JS callback funtion as emscripten::val object. Keep in mind you can't call emscripten::val from threads so maybe track an internal variable that is passed to the threaded function so it can use it as an indicator that the function is complete. This is definitely more complicated than the alternative for simpler use-cases.

Alternate way is to load WASM in a web worker. Make sure you have ENVIRONMENT=web,worker instead of web only. In that case, you can write you C function as a sequential implementation and it'll run within the context of the web worker that initialized it. It'll be same as loading the wasm in normal circumstances. You can load your font information in main thread, pass it to worker thread which in turn passes it to the function call to its own wasm module instance.

  • Related