Thank you!

Great help here. Amazing folks!

On Nov 17, 2017 6:21 PM, "J Decker" <d3c...@gmail.com> wrote:

>
>
> 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/topic/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 a topic in the
> Google Groups "v8-users" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/
> topic/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.
>

-- 
-- 
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