2

I wrote a sample program to pass the Napi::Env object to the child thread for use, but an error occurred during runtime.

the sample code is as follows:

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

Napi::String Method(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();

  // ok
  // Napi::Object obj = Napi::Object::New(env);
  // obj.Set(Napi::String::New(env, "msg"), "hello world");

  // std::string str = obj.Get("msg").As<Napi::String>();
  // std::cout << "str : " << str << std::endl;

  std::thread t([](Napi::Env env) {
    std::cout << "run here 1" << std::endl;
    Napi::Object obj = Napi::Object::New(env);

    std::cout << "run here 2" << std::endl;
    obj.Set(Napi::String::New(env, "msg"), "hello world");

    std::cout << "run here 3" << std::endl;
    std::string str = obj.Get("msg").As<Napi::String>();
    std::cout << "str : " << str << std::endl;
  }, info.Env());
  t.join();

  return Napi::String::New(env, "world");
}

Napi::Object Init(Napi::Env env, Napi::Object exports) {
  exports.Set(Napi::String::New(env, "hello"),
              Napi::Function::New(env, Method));
  return exports;
}

NODE_API_MODULE(hello, Init)

the error is as follows:

enter image description here

thanks for your help!

Robert
  • 31
  • 2

1 Answers1

2

You are not allowed to call V8 primitives from other threads than the main thread - this is one of the most fundamental constraints when writing Node addons.

A Napi::Env is just a pointer, but calling anything in Napi::Object from another thread is not possible.

If you are implementing an async method, you should copy all your arguments from V8 before forking a new thread. The only exceptions to this are ArrayBuffer-backed objects to which you can obtain a pointer in the main thread and then use it in another thread.

mmomtchev
  • 2,497
  • 1
  • 8
  • 23
  • Napi::Env seems a class? https://github.com/nodejs/node-addon-api/blob/main/doc/env.md – Dee Apr 29 '22 at 15:27
  • 1
    It is a class with only one member variable - a `napi_env` pointer. In theory, you can access it from any thread - but in practice all functions that take a `napi_env` as input should be called only from the main thread. – mmomtchev Apr 29 '22 at 15:39