On Fri, Nov 17, 2017 at 7:25 AM, Jean-Marc Le Roux <jeanmarc.ler...@aerys.in
> wrote:

> My assumption is that my test app terminates before the GC has a chance to
> run.
> To test this:
>
>    - I run node with the --expose-gc option
>    - I call global.gc() at the end of my test app
>
> In this case, the destructor of my ObjectWrap is indeed called.
>
> *So it seams the GC doesn't simply "collect everything" when the app
> terminates.*
> *Why is that?*
>
> It sounds like a pretty bad things to do: some behaviors might expect the
> destructor to be called in order to close a socket, etc...
>

because all memory is released. when the app exits.  Why do extra work of
minor side effects?
but ya, if tf you were returning like a file to a handle and expected the
close in order to flush all data out to a device it's bad...

You can attach to Node::AtExit( ... )
https://nodejs.org/api/addons.html#addons_atexit_hooks

which should be called so you an finalize such things.

but sockets get closed by the system when a application exits also.  and
files are closed....



>
> On Friday, November 17, 2017 at 10:27:22 AM UTC+1, Jean-Marc Le Roux wrote:
>>
>> Thanks for the great help!
>> I think it makes a lot of sense now.
>>
>> So I've extended ObjectWrap like so:
>>
>> class BSONObject : public node::ObjectWrap
>>> {
>>> private:
>>>     bson_t* _bson;
>>> public:
>>>     BSONObject(bson_t* bson, Local<ObjectTemplate> tpl) :
>>>         _bson(bson)
>>>     {
>>>         Local<Object> obj = tpl->NewInstance();
>>>         initialize(v8::Isolate::GetCurrent(), obj, bson);
>>>         Wrap(obj);
>>>     }
>>
>>
>>
>>  ~BSONObject()
>>>     {
>>>         std::cout << "~BSONObject()" << std::endl;
>>>         bson_destroy(_bson);
>>>     }
>>
>>
>>
>>     static
>>>     Local<ObjectTemplate>
>>>     create_template(Isolate* isolate, const bson_t* document)
>>>     {
>>>         Local<ObjectTemplate> tpl = ObjectTemplate::New(isolate);
>>>         tpl->SetInternalFieldCount(1);
>>
>>
>> And the "insert" function that I expose in JS and that instanciates the
>> BSONObject is written like this:
>>
>> void
>>> insert(const FunctionCallbackInfo<Value>& args)
>>> {
>>>     Isolate* isolate = args.GetIsolate();
>>>
>>>     db->insert(
>>>         json_stringify(isolate, args[0]),
>>>         [&args, isolate](const bson_t* document)
>>>         {
>>>             if (!args[1]->IsUndefined())
>>>             {
>>>                 Local<Function> callback = Local<Function>::Cast(args[1])
>>> ;
>>>                 Local<Object> obj = Object::New(isolate);
>>>                 *Local<Value> argv[] = { (new
>>> BSONObject(bson_copy(document)))->handle(isolate) };*
>>>                 callback->Call(isolate->GetCurrentContext()->Global(),
>>> 1, argv);
>>>             }
>>>         }
>>>     );
>>> }
>>
>>
>> It runs fine.
>> But the destructor is never called (I never see "~BSONObject()" on
>> stdout).
>>
>> Did I miss something?
>>
>> Thanks !
>>
>> 2017-11-16 22:01 GMT+01:00 J Decker <d3c...@gmail.com>:
>>
>>> You don't manage the instance, the v8 engine does.  When it's no longer
>>> referenced in the engine, it's garbage collected which triggers the
>>> callback set when the perisstent object is made weak.
>>>
>>> You don't need to keep it anywhere, the object returned into the engine
>>> has Internal Fields ( SetInternalFieldCount(1) ) which is used to point to
>>> your native class instance.   So when the callback is called, it knows what
>>> to call to destruct it.
>>>
>>> You have to 'keep it' in the javascript scrpit if you want to keep it,
>>> it's not 'kept' in the native code...
>>>
>>>
>>> --- This is some code I've done that uses setweak directly; but it's
>>> fairly scattered....
>>>
>>> https://github.com/d3x0r/sack.vfs/blob/master/src/jsonParse.cc#L18
>>>
>>> You can create an instance of your wrapped object with
>>>
>>> Local<Function> cons = Local<Function>::New( isolate, constructor );
>>>     cons->NewInstance( isolate->GetCurrentContext(), argc, argv
>>> ).ToLocalChecked() ;
>>>
>>> Hmm that's not the best example source...
>>>
>>> https://github.com/d3x0r/sack.vfs/blob/master/src/vfs_module.cc#L407
>>>
>>> This creates a buffer, and makes it weak...
>>> https://github.com/d3x0r/sack.vfs/blob/master/src/vfs_module.cc#L438
>>>
>>> Local<Object> arrayBuffer = ArrayBuffer::New( isolate, buf, len );
>>> PARRAY_BUFFER_HOLDER holder = GetHolder();
>>> holder->o.Reset( isolate, arrayBuffer );
>>> holder->o.SetWeak<ARRAY_BUFFER_HOLDER>( holder, releaseBuffer,
>>> WeakCallbackType::kParameter );
>>> holder->buffer = buf;
>>>
>>> PARRAY_BUFFER_HOLDER is just a type that holds the thing to be free (or
>>> object containing things to be released), and the persistent reference that
>>> has been made weak...
>>>
>>> struct arrayBufferHolder {
>>> void *buffer;
>>> Persistent<Object> o;
>>> };
>>>
>>>
>>>
>>> On Thu, Nov 16, 2017 at 9:56 AM, Jean-Marc Le Roux <
>>> jeanmarc.ler...@aerys.in> wrote:
>>>
>>>> Node offers a C++ Clss extention ObjectWrap
>>>>
>>>>
>>>> Thanks !
>>>> It is related to node. Yet I'm not sure how I'm supposed to use
>>>> ObjectWrap.
>>>>
>>>> I understand I have to create my own class that extends ObjectWrap and
>>>> implement a proper destructor.
>>>> Then I'll instanciate that class to wrap my Local<Object>. But how do I
>>>> manage such instance?
>>>> If I don't keep it somewhere, it will be destructed.
>>>> If I keep it around, then I'm keeping references to potentially
>>>> deallocated memory.
>>>>
>>>> It feels like I end up with the same problem...
>>>>
>>>> 2017-11-16 18:36 GMT+01:00 J Decker <d3c...@gmail.com>:
>>>>
>>>>>
>>>>>
>>>>> On Thu, Nov 16, 2017 at 1:24 AM, Jean-Marc Le Roux <
>>>>> jeanmarc.ler...@aerys.in> wrote:
>>>>>
>>>>>> I assume you're storing references to the objects as Persistent?
>>>>>>
>>>>>>
>>>>>> Nope. You've got the whole code up there.
>>>>>> So if I understand correctly:
>>>>>>
>>>>>>    - the objects I need to keep track of the lifecycle should be
>>>>>>    made Persistent ;
>>>>>>    - all the other values can be set as Local ;
>>>>>>    - I should set the weak callback using MakeWeak ;
>>>>>>    - callback will be called when such object is GCed and I can free
>>>>>>    my C/C++ memory then.
>>>>>>
>>>>>> Is that correct ?
>>>>>>
>>>>>
>>>>> Yes.  I sthis perhaps related to Node?
>>>>> Node offers a C++ Clss extention ObjectWrap
>>>>>
>>>>> https://nodejs.org/api/addons.html#addons_wrapping_c_objects
>>>>> https://github.com/nodejs/node/blob/master/src/node_object_wrap.h
>>>>>
>>>>> which simplifies that whole process... when the object is GC'd the
>>>>> class destructor will get called so you can release values there.
>>>>>
>>>>>
>>>>>
>>>>>>
>>>>>> 2017-11-15 19:50 GMT+01:00 J Decker <d3c...@gmail.com>:
>>>>>>
>>>>>>> I assume you're storing references to the objects as Persistent?
>>>>>>> All you need to do then is call SetWeak() https://v8docs.nodes
>>>>>>> ource.com/node-0.10/d2/d78/classv8_1_1_persistent.html
>>>>>>> void MakeWeak (void *parameters, WeakReferenceCallback callback)
>>>>>>>
>>>>>>> the callback is called when the object is GC'd.
>>>>>>>
>>>>>>>
>>>>>>> On Wed, Nov 15, 2017 at 8:37 AM, Jean-Marc Le Roux <
>>>>>>> jeanmarc.ler...@aerys.in> wrote:
>>>>>>>
>>>>>>>> So I've found a solution to make things lazy: I set an accessor
>>>>>>>> instead of decoding/setting the actual value.
>>>>>>>>
>>>>>>>> void
>>>>>>>> getter(Local<Name> property, const PropertyCallbackInfo<Value>&
>>>>>>>> info)
>>>>>>>> {
>>>>>>>>     Isolate* isolate = info.GetIsolate();
>>>>>>>>
>>>>>>>>       const bson_t* document = reinterpret_cast<bson_t*>(
>>>>>>>>         info.This()
>>>>>>>>             ->Get(String::NewFromUtf8(isolate,
>>>>>>>> "__bson_document_ptr"))
>>>>>>>>             ->ToInt32()->Value()
>>>>>>>>     );
>>>>>>>>
>>>>>>>>     char key[255];
>>>>>>>>     property->ToString(isolate)->WriteUtf8(key, 255);
>>>>>>>>
>>>>>>>>     bson_iter_t iter;
>>>>>>>>     bson_iter_init(&iter, document);
>>>>>>>>     // FIXME: index the property so we don't have to find it
>>>>>>>>     bson_iter_find(&iter, key);
>>>>>>>>
>>>>>>>>     // FIXME: replace the accessor with the deserialized value
>>>>>>>>
>>>>>>>>     info.GetReturnValue().Set(iterator_to_value(isolate, &iter));
>>>>>>>> }
>>>>>>>>
>>>>>>>> Local<Value>
>>>>>>>> fill_object(Isolate* isolate, Local<Object>& obj, const bson_t*
>>>>>>>> document)
>>>>>>>> {
>>>>>>>>     obj->Set(
>>>>>>>>         String::NewFromUtf8(isolate, "__bson_document_ptr"),
>>>>>>>>         Int32::New(isolate, reinterpret_cast<intptr_t>(document))
>>>>>>>>     );
>>>>>>>>
>>>>>>>>     bson_iter_t iter;
>>>>>>>>     if (bson_iter_init(&iter, document))
>>>>>>>>     {
>>>>>>>>         while (bson_iter_next(&iter))
>>>>>>>>         {
>>>>>>>>             const char* key = bson_iter_key(&iter);
>>>>>>>>
>>>>>>>>                         if (!obj->Has(String::NewFromUtf8(isolate,
>>>>>>>> key)))
>>>>>>>>             {
>>>>>>>>                 obj->SetAccessor(
>>>>>>>>                     isolate->GetCurrentContext(),
>>>>>>>>                     String::NewFromUtf8(isolate, key),
>>>>>>>>                     &getter
>>>>>>>>                 );
>>>>>>>>             }
>>>>>>>>                 }
>>>>>>>>     }
>>>>>>>> }
>>>>>>>>
>>>>>>>> The secret sauce is to :
>>>>>>>>
>>>>>>>>    - keep the original data (the bson_t) allocated
>>>>>>>>    - store the corresponding pointer in a v8::Object
>>>>>>>>
>>>>>>>> But now I have a memory leak because those pointers will never be
>>>>>>>> freed.
>>>>>>>> How can I know when the Object will be disposed by the GC?
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>>
>>>>>>>> --
>>>>>>>> --
>>>>>>>> v8-users mailing list
>>>>>>>> v8-users@googlegroups.com
>>>>>>>> http://groups.google.com/group/v8-users
>>>>>>>> ---
>>>>>>>> You received this message because you are subscribed to the Google
>>>>>>>> Groups "v8-users" group.
>>>>>>>> To unsubscribe from this group and stop receiving emails from it,
>>>>>>>> send an email to v8-users+unsubscr...@googlegroups.com.
>>>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> --
>>>>>>> v8-users mailing list
>>>>>>> v8-users@googlegroups.com
>>>>>>> http://groups.google.com/group/v8-users
>>>>>>> ---
>>>>>>> You received this message because you are subscribed to a topic in
>>>>>>> the Google Groups "v8-users" group.
>>>>>>> To unsubscribe from this topic, visit https://groups.google.com/d/to
>>>>>>> pic/v8-users/aVeevQcHJ2c/unsubscribe.
>>>>>>> To unsubscribe from this group and all its topics, send an email to
>>>>>>> v8-users+unsubscr...@googlegroups.com.
>>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> *Jean-Marc Le Roux*
>>>>>>
>>>>>>
>>>>>> Founder and CEO of Aerys (http://aerys.in)
>>>>>>
>>>>>> Blog: http://blogs.aerys.in/jeanmarc-leroux
>>>>>> Cell: (+33)6 20 56 45 78
>>>>>> Phone: (+33)9 72 40 17 58
>>>>>>
>>>>>> --
>>>>>> --
>>>>>> v8-users mailing list
>>>>>> v8-users@googlegroups.com
>>>>>> http://groups.google.com/group/v8-users
>>>>>> ---
>>>>>> You received this message because you are subscribed to the Google
>>>>>> Groups "v8-users" group.
>>>>>> To unsubscribe from this group and stop receiving emails from it,
>>>>>> send an email to v8-users+unsubscr...@googlegroups.com.
>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>
>>>>>
>>>>> --
>>>>> --
>>>>> v8-users mailing list
>>>>> v8-users@googlegroups.com
>>>>> http://groups.google.com/group/v8-users
>>>>> ---
>>>>> You received this message because you are subscribed to a topic in the
>>>>> Google Groups "v8-users" group.
>>>>> To unsubscribe from this topic, visit https://groups.google.com/d/to
>>>>> pic/v8-users/aVeevQcHJ2c/unsubscribe.
>>>>> To unsubscribe from this group and all its topics, send an email to
>>>>> v8-users+unsubscr...@googlegroups.com.
>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> *Jean-Marc Le Roux*
>>>>
>>>>
>>>> Founder and CEO of Aerys (http://aerys.in)
>>>>
>>>> Blog: http://blogs.aerys.in/jeanmarc-leroux
>>>> Cell: (+33)6 20 56 45 78
>>>> Phone: (+33)9 72 40 17 58
>>>>
>>>> --
>>>> --
>>>> v8-users mailing list
>>>> v8-users@googlegroups.com
>>>> http://groups.google.com/group/v8-users
>>>> ---
>>>> You received this message because you are subscribed to the Google
>>>> Groups "v8-users" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>> an email to v8-users+unsubscr...@googlegroups.com.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>
>>> --
>>> --
>>> v8-users mailing list
>>> v8-users@googlegroups.com
>>> http://groups.google.com/group/v8-users
>>> ---
>>> You received this message because you are subscribed to a topic in the
>>> Google Groups "v8-users" group.
>>> To unsubscribe from this topic, visit https://groups.google.com/d/to
>>> pic/v8-users/aVeevQcHJ2c/unsubscribe.
>>> To unsubscribe from this group and all its topics, send an email to
>>> v8-users+unsubscr...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>
>>
>> --
>> *Jean-Marc Le Roux*
>>
>>
>> Founder and CEO of Aerys (http://aerys.in)
>>
>> Blog: http://blogs.aerys.in/jeanmarc-leroux
>> Cell: (+33)6 20 56 45 78 <+33%206%2020%2056%2045%2078>
>> Phone: (+33)9 72 40 17 58 <+33%209%2072%2040%2017%2058>
>>
> --
> --
> v8-users mailing list
> v8-users@googlegroups.com
> http://groups.google.com/group/v8-users
> ---
> You received this message because you are subscribed to the Google Groups
> "v8-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to v8-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
-- 
v8-users mailing list
v8-users@googlegroups.com
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to