Passing a Buffer from C++ to a callback - object lifetime?

105 views
Skip to first unread message

Andy C

unread,
Aug 13, 2015, 6:09:39 PM8/13/15
to nodejs
Hi,
I am writing a C++ module for node. I have a JS callback registered which will receive regular callbacks with binary data (audio data).

My C++ to call the callback looks a bit like:

    UniquePersistent<v8::Function> dataCallback = // from somewhere...

    HandleScope scope(isolate);

    const unsigned argc = 1;
    auto buffer = node::Buffer::New(dataSize);
    std::memcpy(node::Buffer::Data(buffer), data.get(), dataSize);

    Local<Value> argv[argc] = { buffer };

    auto fn = Local<Function>::New(isolate, dataCallback);
    auto context = isolate->GetCurrentContext();
    auto global = context->Global();
    fn->Call(global, argc, argv);

At the moment my callback is simply passing the buffer on to fs.writeFile(...):

    var fs = require('fs');
    mymodule.dosomething(function(data) {
        fs.writeFile('raw_data', data, { flag: 'a' })
    });

This appears to work, however the lifetime of the buffer object is suspect. This seems unsafe, as my understanding is that the Local<Buffer> is going to be cleared up when the HandleScope is destroyed after the callback has returned. Unfortunately, fs.writeFile() is probably still busy with the buffer.

The key would seem to be something to do with Persistent<> and UniquePersistent<> but I don't quite grok it.

Any tips, or pointers to examples would be great...


Andy C

unread,
Aug 14, 2015, 9:33:24 AM8/14/15
to nodejs
Maybe it is not as bad as I thought. I missed a bit of a sentence in the V8 embedder's guide:

When the destructor, HandleScope::~HandleScope, is called the handle scope is deleted. Objects referred to by handles within the deleted handle scope are eligible for removal in the next garbage collection if there are no other references to them.

I think this means that because fs.writeFile() has a reference to the Buffer, it will not be garbage collected, and the memory held on to.

Andy

Loïc PORTALES

unread,
Aug 15, 2015, 4:48:11 PM8/15/15
to nodejs

Hello,

Yes, while your handles are in an handle scope they will not be deleted. So in your case you do not need to use a persistent handle.

You must use a persistent handle only in case you want to keep an object which is no longer in a handle context. For example, if you got the handle on a callback function from the main thread then you use it from an other thread, you must use a persistent handle, to make sure it will not be deleted while there is no handle context holding it.

About the persistent handle, be careful to release it : http://izs.me/v8-docs/classv8_1_1Persistent.html#a33e53191844272ba0f2da4f55fc12297

Loïc

Andy C

unread,
Aug 18, 2015, 12:07:49 AM8/18/15
to nodejs
Thanks for the reply Loïc
Reply all
Reply to author
Forward
0 new messages