leaningtech / cheerp-meta

Cheerp - a C/C++ compiler for Web applications - compiles to WebAssembly and JavaScript
https://labs.leaningtech.com/cheerp
Other
1.02k stars 50 forks source link

'web workers' example generally does not appear to be producing console output #157

Open DXXS opened 1 month ago

DXXS commented 1 month ago

Reported on discord: 'web workers' example (compiled with 'Cheerp 3.0 clang version 16.0.0' on osx) generally does not appear to be producing the claimed "Hello World" console output for me in normal usage... if I load the web page ('Chrome' v127.x), open their 'inspector', and then place breakpoints at the addEventListener() calls in each js file, as well as at the console.log call itself, and then single step until completion, the console.log calls can be reached, and the messages do then appear in console output, otherwise they don't appear to be doing so at the moment...

web_worker_debug
alexp-sssup commented 1 month ago

The underlying problem is that the worker can lose messages since compiling wasm code is asynchronous.

This is a general web worker issue, not connected to Cheerp, but the example needs to be modified to take that into account

Please try with the following modified sources:

cheerpWorkerHost.cpp

// cheerpWorkerHost.cpp: Code to include in the HTML page
#include <cheerp/client.h>
#include <cheerp/clientlib.h>

using namespace client;

[[cheerp::genericjs]]
void webMain()
{
        Worker* w = new Worker("cheerpWorker.js");
        w->addEventListener("message", cheerp::Callback([w](MessageEvent* e) {
                if(e->get_data() == nullptr)
                        w->postMessage(String("Hello World"));
                else
                        console.log((String*)(e->get_data()));
        }));
}

cheerpWorker.cpp

// cheerpWorker.cpp: Code that runs inside the worker
#include <cheerp/clientlib.h>
#include <cheerp/client.h>

using namespace client;

[[cheerp::genericjs]]
void webMain()
{
       addEventListener("message", cheerp::Callback([](MessageEvent* e) {
                               postMessage(e->get_data());
                               postMessage(e->get_data());
                               }));
        postMessage(nullptr);
}                       

The idea for the new approach is to wait for the worker to be ready before attempting to send an actual message. The first null message is interpreted as "ready" message.

We will close this issue when the docs are updated