Skip to content
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

JS thread blocked when calling Wasm #20982

Open
idanran opened this issue Dec 26, 2023 · 2 comments
Open

JS thread blocked when calling Wasm #20982

idanran opened this issue Dec 26, 2023 · 2 comments

Comments

@idanran
Copy link

idanran commented Dec 26, 2023

Version of emscripten/emsdk:

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.51 (c0c2ca1314672a25699846b4663701bcb6f69cca)
clang version 18.0.0git (https://github.com/llvm/llvm-project f2464ca317bfeeedddb7cbdea3c2c8ec487890bb)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: D:\develop\emsdk\upstream\bin

link command:

set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS  "-lembind -sALLOW_MEMORY_GROWTH -sEXPORT_ES6 -sINVOKE_RUN=0 --embind-emit-tsd silk_wasm.d.ts")
)

C++ code:

extern "C"
{
#include <common.h>
#include <codec.h>
}
#include <emscripten/bind.h>
#include <emscripten/val.h>
using namespace std;
using namespace emscripten;

typedef struct codec_ctx
{
    val cb;
} codec_ctx_t;

void codec_callback(void *userdata, unsigned char *data, int len)
{
    codec_ctx_t ctx = *(codec_ctx_t *)userdata;
    ctx.cb(val(typed_memory_view(len, data)));
}

int silk_encode(std::string data, int data_len, int sample_rate, val cb)
{
    codec_ctx_t ctx = {cb};
    unsigned char* uc = (unsigned char*) data.c_str();
    int ret = silkEncode(uc, data_len, sample_rate, codec_callback, &ctx);
    return ret;
}

EMSCRIPTEN_BINDINGS(module)
{
    emscripten::function("silk_encode", &silk_encode);
}

Typescript code:

import Instance from './silk_wasm.js'
import { concat } from './utils'

export interface encodeResult {
    data: Uint8Array
    duration: number
}

export async function encode(input: Uint8Array, sampleRate: number): Promise<encodeResult> {
    const instance = await Instance()

    const arr: Uint8Array[] = []
    let totalLength = 0

    const ret = instance.silk_encode(input, input.length, sampleRate, (chunk: Uint8Array) => {
        totalLength += chunk.length
        arr.push(Uint8Array.from(chunk))
    })

    if (ret === 0) throw new Error('silk encoding failure')

    return {
        data: concat(arr, totalLength).slice(0, -1),
        duration: ret
    }
}

When I run the encode function in the Typescript code, the JS thread is blocked. How can I solve this?

@sbc100
Copy link
Collaborator

sbc100 commented Jan 4, 2024

I assume the work in silk_encode is something takes some amount of time and you don't want to have the main thread block while its running? IIUC that only way run such work in the background would be do so on a thread.

Then you probably want to have silk_encode return a promise which the encode function calls await on. The C++ code can/should then resolve the promise once that background thread is done processing. Note that promises and embind values all live on a specific thread, so you would likely need to do the promise resolution back on the back thread.

@tlively @RReverser do you have that about right?

@idanran
Copy link
Author

idanran commented Jan 9, 2024

I assume the work in silk_encode is something takes some amount of time and you don't want to have the main thread block while its running? IIUC that only way run such work in the background would be do so on a thread.

Then you probably want to have silk_encode return a promise which the encode function calls await on. The C++ code can/should then resolve the promise once that background thread is done processing. Note that promises and embind values all live on a specific thread, so you would likely need to do the promise resolution back on the back thread.

@tlively @RReverser do you have that about right?

Do I have to use a Worker?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants