node-addon-api
node-addon-api copied to clipboard
Strange behavior
I'm new to nodejs, I took embedtest from nodejs and added napi to it, this way I got C++ Embed, after C++/nodejs/v8 is done I will get control back.
v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, s.c_str(), v8::NewStringType::kNormal).ToLocalChecked();
v8::Local<v8::Script> script = v8::Script::Compile(context, source).ToLocalChecked();
v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
The execution of the script itself will create an idle function registration on the js side:
import { player_t, StatusCode } from './player'
const player = new player_t();
player.registerIdle(() => {
console.log(player.getLogin());
});
The player_t class is still on the js side, it talks to C++; So the registration looks like this:
registerIdle(idleFunction: (player: player_t) => void) {
this.player.registerIdle(idleFunction);
}
I use NapiAddon
...
InstanceMethod<&player_core_t::registerIdle>(
"registerIdle",
static_cast<napi_property_attributes>(napi_writable |
napi_configurable)),
...
Simple FunctionRef registration:
Napi::Value registerIdle(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
if (info.Length() != 1) {
Napi::Error::New(env, "Invalid argument count")
.ThrowAsJavaScriptException();
return info.Env().Undefined();
}
if (!info[0].IsFunction()) {
Napi::Error::New(env, "First argument not function")
.ThrowAsJavaScriptException();
return info.Env().Undefined();
}
IdleFunction = Napi::Persistent(info[0].As<Napi::Function>());
return info.Env().Undefined();
}
After script->Run I receive a stream and try to call idleFunc in a loop that will call a js function:
for (size_t i = 0; i < 10000000; i++) {
for (auto& players : player_core_t::listPlayers) {
players->idleFunc();
}
void idleFunc() {
if (playerRef.IsEmpty())
return;
IdleFunction.Call({});
}
The js side method is called and from the idle function lambda the other methods are working correctly. But I'm getting a memory leak. The memory is flying up in megabytes and I don’t understand the reason. It is logical that idle should constantly receive control from the thread.
What did I do wrong? Are there any workarounds?
I tested on nodejs18 and nodejs20. player_example.zip