Skip to content

Need clarity on parameters to the API napi_create_threadsafe_function #336

@varun-elear

Description

@varun-elear

I have a C library. When say_hello() in the library is invoked, it spawns a thread t1 to compute some task T on it and immediately returns from the called function. After the task T has been completed, the callback function received as input to say_hello() is called.

I am using N-API so that the function say_hello() can be used by JS via a napi layer. Since, the thread t1 will call a function in the napi layer as callback, I have to use threadsafe function to transfer control to the main thread so I can call JS functions.

  1. I understood that async_work provided by N-API cannot be used without modifying the C library that I have because threads are created in the C layer and not in the napi layer. Is that correct?

My JS code calls napi_init_app() which creates a threadsafe function. Then napi_say_hello() is called from JS which in turn calls say_hello() and returns.

A napi_ref to the JS callback function js_hello_callback() which was passed as parameter to napi_say_hello() is passed down to the C layer so that it can be retrieved back when the napi_hello_callback() is called by the thread t1.

napi_hello_callback() calls the API napi_call_threadsafe_function() and passes the napi_ref to js_hello_callback() along. call_js_cb() is then invoked which retrieves js_hello_callback() as napi_value from napi_ref and invokes it.

I do not do napi_acquire_threadsafe_function or napi_release_threadsafe_function for every call to the threadsafe function and only call napi_release_threadsafe_function when JS layer calls napi_destroy_app().

I have the following queries regarding the threadsafe APIs:

  1. func (The JavaScript function to call from another thread) - This is a mandatory parameter but I cannot find a use case for this in the above scenario because napi_say_hello() can be called each time with a different callback. Am I missing something or should this be optional?
  2. initial_thread_count - The number of times napi_say_hello() will be called or the number of threads which will call it is unknown to me when I am creating the threadsafe function. So, I am passing 1 as the value and neither acquiring or releasing before napi_destroy_app() is called. Why do we actually need this count?
  3. context - Also, this could be of more use if we could store different context for each call. Could you please provide some example for utilising this parameter.

I have the following queries regarding my approach:

  1. Is creating one threadsafe function for each function similar to say_hello(), the right approach?
  2. Am I creating and releasing the threadsafe function at the right time?
  3. Could I use a better approach for my use case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions