@ 260902.1raw
current

ThreadSafeFunction

The Napi::ThreadSafeFunction type provides APIs for threads to communicate with the addon’s main thread to invoke JavaScript functions on their behalf. Documentation can be found for an overview of the API, as well as differences between the two thread-safe function APIs.

Methods

Constructor

Creates a new empty instance of Napi::ThreadSafeFunction.

Napi::Function::ThreadSafeFunction();

Constructor

Creates a new instance of the Napi::ThreadSafeFunction object.

Napi::ThreadSafeFunction::ThreadSafeFunction(napi_threadsafe_function tsfn);

Returns a non-empty Napi::ThreadSafeFunction instance. When using this constructor, only use the Blocking(void*) / NonBlocking(void*) overloads; the Callback and templated data* overloads should not be used. See below for additional details.

New

Creates a new instance of the Napi::ThreadSafeFunction object. The New function has several overloads for the various optional parameters: skip the optional parameter for that specific overload.

New(napi_env env,
    const Function& callback,
    const Object& resource,
    ResourceString resourceName,
    size_t maxQueueSize,
    size_t initialThreadCount,
    ContextType* context,
    Finalizer finalizeCallback,
    FinalizerDataType* data);

Returns a non-empty Napi::ThreadSafeFunction instance.

Acquire

Add a thread to this thread-safe function object, indicating that a new thread will start making use of the thread-safe function.

napi_status Napi::ThreadSafeFunction::Acquire() const

Returns one of:

Release

Indicate that an existing thread will stop making use of the thread-safe function. A thread should call this API when it stops making use of this thread-safe function. Using any thread-safe APIs after having called this API has undefined results in the current thread, as it may have been destroyed.

napi_status Napi::ThreadSafeFunction::Release() const

Returns one of:

Abort

“Abort” the thread-safe function. This will cause all subsequent APIs associated with the thread-safe function except Release() to return napi_closing even before its reference count reaches zero. In particular, BlockingCall and NonBlockingCall() will return napi_closing, thus informing the threads that it is no longer possible to make asynchronous calls to the thread-safe function. This can be used as a criterion for terminating the thread. Upon receiving a return value of napi_closing from a thread-safe function call a thread must make no further use of the thread-safe function because it is no longer guaranteed to be allocated.

napi_status Napi::ThreadSafeFunction::Abort() const

Returns one of:

BlockingCall / NonBlockingCall

Calls the Javascript function in either a blocking or non-blocking fashion.

There are several overloaded implementations of BlockingCall() and NonBlockingCall() for use with optional parameters: skip the optional parameter for that specific overload.

These specific function overloads should only be used on a ThreadSafeFunction created via ThreadSafeFunction::New.

napi_status Napi::ThreadSafeFunction::BlockingCall(DataType* data, Callback callback) const

napi_status Napi::ThreadSafeFunction::NonBlockingCall(DataType* data, Callback callback) const

These specific function overloads should only be used on a ThreadSafeFunction created via ThreadSafeFunction(napi_threadsafe_function).

napi_status Napi::ThreadSafeFunction::BlockingCall(void* data) const

napi_status Napi::ThreadSafeFunction::NonBlockingCall(void* data) const

Returns one of:

Example

#include <chrono>
#include <thread>
#include <napi.h>

using namespace Napi;

std::thread nativeThread;
ThreadSafeFunction tsfn;

Value Start( const CallbackInfo& info )
{
  Napi::Env env = info.Env();

  if ( info.Length() < 2 )
  {
    throw TypeError::New( env, "Expected two arguments" );
  }
  else if ( !info[0].IsFunction() )
  {
    throw TypeError::New( env, "Expected first arg to be function" );
  }
  else if ( !info[1].IsNumber() )
  {
    throw TypeError::New( env, "Expected second arg to be number" );
  }

  int count = info[1].As<Number>().Int32Value();

  // Create a ThreadSafeFunction
  tsfn = ThreadSafeFunction::New(
      env,
      info[0].As<Function>(),  // JavaScript function called asynchronously
      "Resource Name",         // Name
      0,                       // Unlimited queue
      1,                       // Only one thread will use this initially
      []( Napi::Env ) {        // Finalizer used to clean threads up
        nativeThread.join();
      } );

  // Create a native thread
  nativeThread = std::thread( [count] {
    auto callback = []( Napi::Env env, Function jsCallback, int* value ) {
      // Transform native data into JS data, passing it to the provided
      // `jsCallback` -- the TSFN's JavaScript function.
      jsCallback.Call( {Number::New( env, *value )} );

      // We're finished with the data.
      delete value;
    };

    for ( int i = 0; i < count; i++ )
    {
      // Create new data
      int* value = new int( clock() );

      // Perform a blocking call
      napi_status status = tsfn.BlockingCall( value, callback );
      if ( status != napi_ok )
      {
        // Handle error
        break;
      }

      std::this_thread::sleep_for( std::chrono::seconds( 1 ) );
    }

    // Release the thread-safe function
    tsfn.Release();
  } );

  return Boolean::New(env, true);
}

Napi::Object Init( Napi::Env env, Object exports )
{
  exports.Set( "start", Function::New( env, Start ) );
  return exports;
}

NODE_API_MODULE( clock, Init )

The above code can be used from JavaScript as follows:

const { start } = require('bindings')('clock');

start(function () {
    console.log("JavaScript callback called with arguments", Array.from(arguments));
}, 5);

When executed, the output will show the value of clock() five times at one second intervals:

JavaScript callback called with arguments [ 84745 ]
JavaScript callback called with arguments [ 103211 ]
JavaScript callback called with arguments [ 104516 ]
JavaScript callback called with arguments [ 105104 ]
JavaScript callback called with arguments [ 105691 ]