From f9159ea2d994e14180fb02ab562f0119513e67cf Mon Sep 17 00:00:00 2001 From: 8cy <50817549+8cy@users.noreply.github.com> Date: Fri, 3 Apr 2020 02:48:28 -0700 Subject: 2020/04/03, 02:47, V1.2.2 --- .../node-addon-api/doc/threadsafe_function.md | 320 --------------------- 1 file changed, 320 deletions(-) delete mode 100644 node_modules/node-addon-api/doc/threadsafe_function.md (limited to 'node_modules/node-addon-api/doc/threadsafe_function.md') diff --git a/node_modules/node-addon-api/doc/threadsafe_function.md b/node_modules/node-addon-api/doc/threadsafe_function.md deleted file mode 100644 index 2bd8b67..0000000 --- a/node_modules/node-addon-api/doc/threadsafe_function.md +++ /dev/null @@ -1,320 +0,0 @@ -# ThreadSafeFunction - -JavaScript functions can normally only be called from a native addon's main -thread. If an addon creates additional threads, then node-addon-api functions -that require a `Napi::Env`, `Napi::Value`, or `Napi::Reference` must not be -called from those threads. - -When an addon has additional threads and JavaScript functions need to be invoked -based on the processing completed by those threads, those threads must -communicate with the addon's main thread so that the main thread can invoke the -JavaScript function on their behalf. The thread-safe function APIs provide an -easy way to do this. - -These APIs provide the type `Napi::ThreadSafeFunction` as well as APIs to -create, destroy, and call objects of this type. -`Napi::ThreadSafeFunction::New()` creates a persistent reference that holds a -JavaScript function which can be called from multiple threads. The calls happen -asynchronously. This means that values with which the JavaScript callback is to -be called will be placed in a queue, and, for each value in the queue, a call -will eventually be made to the JavaScript function. - -`Napi::ThreadSafeFunction` objects are destroyed when every thread which uses -the object has called `Release()` or has received a return status of -`napi_closing` in response to a call to `BlockingCall()` or `NonBlockingCall()`. -The queue is emptied before the `Napi::ThreadSafeFunction` is destroyed. It is -important that `Release()` be the last API call made in conjunction with a given -`Napi::ThreadSafeFunction`, because after the call completes, there is no -guarantee that the `Napi::ThreadSafeFunction` is still allocated. For the same -reason it is also important that no more use be made of a thread-safe function -after receiving a return value of `napi_closing` in response to a call to -`BlockingCall()` or `NonBlockingCall()`. Data associated with the -`Napi::ThreadSafeFunction` can be freed in its `Finalizer` callback which was -passed to `ThreadSafeFunction::New()`. - -Once the number of threads making use of a `Napi::ThreadSafeFunction` reaches -zero, no further threads can start making use of it by calling `Acquire()`. In -fact, all subsequent API calls associated with it, except `Release()`, will -return an error value of `napi_closing`. - -## Methods - -### Constructor - -Creates a new empty instance of `Napi::ThreadSafeFunction`. - -```cpp -Napi::Function::ThreadSafeFunction(); -``` - -### Constructor - -Creates a new instance of the `Napi::ThreadSafeFunction` object. - -```cpp -Napi::ThreadSafeFunction::ThreadSafeFunction(napi_threadsafe_function tsfn); -``` - -- `tsfn`: The `napi_threadsafe_function` which is a handle for an existing - thread-safe function. - -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. - -```cpp -New(napi_env env, - const Function& callback, - const Object& resource, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context, - Finalizer finalizeCallback, - FinalizerDataType* data); -``` - -- `env`: The `napi_env` environment in which to construct the - `Napi::ThreadSafeFunction` object. -- `callback`: The `Function` to call from another thread. -- `[optional] resource`: An object associated with the async work that will be - passed to possible async_hooks init hooks. -- `resourceName`: A JavaScript string to provide an identifier for the kind of - resource that is being provided for diagnostic information exposed by the - async_hooks API. -- `maxQueueSize`: Maximum size of the queue. `0` for no limit. -- `initialThreadCount`: The initial number of threads, including the main - thread, which will be making use of this function. -- `[optional] context`: Data to attach to the resulting `ThreadSafeFunction`. -- `[optional] finalizeCallback`: Function to call when the `ThreadSafeFunction` - is being destroyed. This callback will be invoked on the main thread when the - thread-safe function is about to be destroyed. It receives the context and the - finalize data given during construction (if given), and provides an - opportunity for cleaning up after the threads e.g. by calling - `uv_thread_join()`. It is important that, aside from the main loop thread, - there be no threads left using the thread-safe function after the finalize - callback completes. Must implement `void operator()(Env env, DataType* data, - Context* hint)`, skipping `data` or `hint` if they are not provided. - Can be retreived via `GetContext()`. -- `[optional] data`: Data to be passed to `finalizeCallback`. - -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. - -```cpp -napi_status Napi::ThreadSafeFunction::Acquire() -``` - -Returns one of: -- `napi_ok`: The thread has successfully acquired the thread-safe function -for its use. -- `napi_closing`: The thread-safe function has been marked as closing via a -previous call to `Abort()`. - -### 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. - -```cpp -napi_status Napi::ThreadSafeFunction::Release() -``` - -Returns one of: -- `napi_ok`: The thread-safe function has been successfully released. -- `napi_invalid_arg`: The thread-safe function's thread-count is zero. -- `napi_generic_failure`: A generic error occurred when attemping to release -the thread-safe function. - -### 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. - -```cpp -napi_status Napi::ThreadSafeFunction::Abort() -``` - -Returns one of: -- `napi_ok`: The thread-safe function has been successfully aborted. -- `napi_invalid_arg`: The thread-safe function's thread-count is zero. -- `napi_generic_failure`: A generic error occurred when attemping to abort -the thread-safe function. - -### BlockingCall / NonBlockingCall - -Calls the Javascript function in either a blocking or non-blocking fashion. -- `BlockingCall()`: the API blocks until space becomes available in the queue. - Will never block if the thread-safe function was created with a maximum queue - size of `0`. -- `NonBlockingCall()`: will return `napi_queue_full` if the queue was full, - preventing data from being successfully added to the queue. - -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`.** - -```cpp -napi_status Napi::ThreadSafeFunction::BlockingCall(DataType* data, Callback callback) const - -napi_status Napi::ThreadSafeFunction::NonBlockingCall(DataType* data, Callback callback) const -``` - -- `[optional] data`: Data to pass to `callback`. -- `[optional] callback`: C++ function that is invoked on the main thread. The - callback receives the `ThreadSafeFunction`'s JavaScript callback function to - call as an `Napi::Function` in its parameters and the `DataType*` data pointer - (if provided). Must implement `void operator()(Napi::Env env, Function - jsCallback, DataType* data)`, skipping `data` if not provided. It is not - necessary to call into JavaScript via `MakeCallback()` because N-API runs - `callback` in a context appropriate for callbacks. - -**These specific function overloads should only be used on a `ThreadSafeFunction` -created via `ThreadSafeFunction(napi_threadsafe_function)`.** - -```cpp -napi_status Napi::ThreadSafeFunction::BlockingCall(void* data) const - -napi_status Napi::ThreadSafeFunction::NonBlockingCall(void* data) const -``` -- `data`: Data to pass to `call_js_cb` specified when creating the thread-safe - function via `napi_create_threadsafe_function`. - -Returns one of: -- `napi_ok`: The call was successfully added to the queue. -- `napi_queue_full`: The queue was full when trying to call in a non-blocking - method. -- `napi_closing`: The thread-safe function is aborted and cannot accept more - calls. -- `napi_invalid_arg`: The thread-safe function is closed. -- `napi_generic_failure`: A generic error occurred when attemping to add to the - queue. - -## Example - -```cpp -#include -#include -#include - -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().Int32Value(); - - // Create a ThreadSafeFunction - tsfn = ThreadSafeFunction::New( - env, - info[0].As(), // 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: - -```js -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 ] -``` -- cgit v1.2.3