From dfb0a3c08f52bb301addfc310d69ac46ec5c0c33 Mon Sep 17 00:00:00 2001 From: Charles Lowell Date: Mon, 6 Jul 2015 01:19:59 -0500 Subject: [PATCH] more documentation on external --- ext/v8/external.cc | 10 ++++++++-- ext/v8/external.h | 8 ++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ext/v8/external.cc b/ext/v8/external.cc index fa6adfd..45b3d84 100644 --- a/ext/v8/external.cc +++ b/ext/v8/external.cc @@ -13,17 +13,23 @@ namespace rr { VALUE External::New(VALUE self, VALUE r_isolate, VALUE object) { Isolate isolate(r_isolate); + + // as long as this external is alive within JavaScript, it should not be + // garbage collected by Ruby. isolate.retainObject(object); Locker lock(isolate); + // create the external. Container* container = new Container(object); v8::Local external(v8::External::New(isolate, (void*)container)); + // next, we create a weak reference to this external so that we can be + // notified when V8 is done with it. At that point, we can let Ruby know + // that this external is done with it. v8::Global* global(new v8::Global(isolate, external)); - container->global = global; - global->SetWeak(container, &release, v8::WeakCallbackType::kParameter); + container->global = global; return External(isolate, external); } diff --git a/ext/v8/external.h b/ext/v8/external.h index b9b9e32..5a26e14 100644 --- a/ext/v8/external.h +++ b/ext/v8/external.h @@ -21,6 +21,14 @@ namespace rr { VALUE object; }; + /** + * Implements a v8::WeakCallbackInfo::Callback with all + * of its idiosyncracies. It happens in two passes. In the first + * pass, you are required to only reset the weak reference. In the + * second pass, you can actually do your cleanup. In this case, we + * schedule the referenced Ruby object to be released in the next + * Ruby gc pass. + */ static void release(const v8::WeakCallbackInfo& info) { Container* container(info.GetParameter()); if (info.IsFirstPass()) {