工作线程的支持


为了从多个 Node.js 环境(例如主线程和工作线程)加载,插件需要:

    In order to be loaded from multiple Node.js environments, such as a main thread and a Worker thread, an add-on needs to either:

    • Be an Node-API addon, or
    • Be declared as context-aware using NODE_MODULE_INIT() as described above

    In order to support Worker threads, addons need to clean up any resources they may have allocated when such a thread exists. This can be achieved through the usage of the AddEnvironmentCleanupHook() function:

    void AddEnvironmentCleanupHook(v8::Isolate* isolate,
                                   void (*fun)(void* arg),
                                   void* arg);

    This function adds a hook that will run before a given Node.js instance shuts down. If necessary, such hooks can be removed before they are run using RemoveEnvironmentCleanupHook(), which has the same signature. Callbacks are run in last-in first-out order.

    If necessary, there is an additional pair of AddEnvironmentCleanupHook() and RemoveEnvironmentCleanupHook() overloads, where the cleanup hook takes a callback function. This can be used for shutting down asynchronous resources, such as any libuv handles registered by the addon.

    The following addon.cc uses AddEnvironmentCleanupHook:

    // addon.cc
    #include <node.h>
    #include <assert.h>
    #include <stdlib.h>
    
    using node::AddEnvironmentCleanupHook;
    using v8::HandleScope;
    using v8::Isolate;
    using v8::Local;
    using v8::Object;
    
    // Note: In a real-world application, do not rely on static/global data.
    static char cookie[] = "yum yum";
    static int cleanup_cb1_called = 0;
    static int cleanup_cb2_called = 0;
    
    static void cleanup_cb1(void* arg) {
      Isolate* isolate = static_cast<Isolate*>(arg);
      HandleScope scope(isolate);
      Local<Object> obj = Object::New(isolate);
      assert(!obj.IsEmpty());  // assert VM is still alive
      assert(obj->IsObject());
      cleanup_cb1_called++;
    }
    
    static void cleanup_cb2(void* arg) {
      assert(arg == static_cast<void*>(cookie));
      cleanup_cb2_called++;
    }
    
    static void sanity_check(void*) {
      assert(cleanup_cb1_called == 1);
      assert(cleanup_cb2_called == 1);
    }
    
    // Initialize this addon to be context-aware.
    NODE_MODULE_INIT(/* exports, module, context */) {
      Isolate* isolate = context->GetIsolate();
    
      AddEnvironmentCleanupHook(isolate, sanity_check, nullptr);
      AddEnvironmentCleanupHook(isolate, cleanup_cb2, cookie);
      AddEnvironmentCleanupHook(isolate, cleanup_cb1, isolate);
    }

    Test in JavaScript by running:

    // test.js
    require('./build/Release/addon');