Venemo
Venemo

Reputation: 19107

How can I attach an event handler to the process's exit in a native Node.js module?

I'm working on implementing correct memory management for a native Node.js module. I've ran into the problem described in this question:
node.js native addon - destructor of wrapped class doesn't run

The suggested solution is to bind the destructors of native objects to process.on('exit'), however the answer does not contain how to do that in a native module.

I've taken a brief look at the libuv docs as well, but they didn't contain anything useful in this regard, either.

NOTE: I'm not particularly interested in getting the process object, but I tried it that way:

auto globalObj = NanGetCurrentContext()->Global();
auto processObj = ::v8::Handle<::v8::Object>::Cast(globalObj->Get(NanNew<String>("process")));
auto processOnFunc = ::v8::Handle<::v8::Function>::Cast(processObj->Get(NanNew<String>("on")));
Handle<Value> processOnExitArgv[2] = { NanNew<String>("exit"), NanNew<FunctionTemplate>(onProcessExit)->GetFunction() };
processOnFunc->Call(processObj, 2, processOnExitArgv);

The problem then is that I get this message when trying to delete my object:

Assertion `persistent().IsNearDeath()' failed.

I also tried to use std::atexit and got the same assertion error.

So far, the best I could do is collecting stray ObjectWrap instances in an std::set and cleaning up the wrapped objects, but because of the above error, I was unable to clean up the wrappers themselves.

So, how can I do this properly?

Upvotes: 1

Views: 1160

Answers (1)

djulien
djulien

Reputation: 141

I was also getting the "Assertion persistent().IsNearDeath()' failed" message.

There is a node::AtExit() function that runs just before Node.js shuts down - the equivalent of process.on('exit').

Pass a callback function to node::AtExit from within your add-on's init function (or where ever is appropriate).

The function is documented here: https://nodejs.org/api/addons.html#addons_atexit_hooks

For example:

NAN_MODULE_INIT(my_exports)
{
// other exported stuff here
    node::AtExit(my_cleanup);
}

NODE_MODULE(my_module, my_exports) //add-on exports

//call C++ dtors:
void my_cleanup()
{
    delete my_object_ptr; //call object dtor, or other stuff that needs to be cleaned up here
}

Upvotes: 1

Related Questions