The object disappearing randomly/unexpectedly is not a problem as we will always call the napi_get_reference_value API. This API will return NULL if the underlying object is garbage collected.
We have a couple of requirements for the correct implementation of napi_get_reference_value API.
1) We need a way to know that the object is garbage collected, something like FinalizeCallback which is set using _persistent.SetWeak. The _persistent is reset only in the FinalizeCallback and not before ( code below)
2) We need to keep the underlying object to be valid with a reference count of 0 until it is garbage collected( if someone tries to Ref the object we perform ClearWeak on the _persistent ).
- Code: Select all
v8::Persistent<T> _persistent;
static void FinalizeCallback(const v8::WeakCallbackInfo<Reference>& data) {
Reference* reference = data.GetParameter();
reference->_persistent.Reset();
}
uint32_t Ref() {
if (++_refcount == 1) {
_persistent.ClearWeak();
}
return _refcount;
}
uint32_t Unref() {
if (_refcount == 0) {
return 0;
}
if (--_refcount == 0) {
_persistent.SetWeak(
this, FinalizeCallback, v8::WeakCallbackType::kParameter);
_persistent.MarkIndependent();
}
return _refcount;
}
uint32_t RefCount() {
return _refcount;
}
v8::Local<T> Get() {
if (_persistent.IsEmpty()) {
return NULL;
} else {
return v8::Local<T>::New(_env->isolate, _persistent);
}
}