Skip to content

Commit

Permalink
Allow delete weak ref from user's side
Browse files Browse the repository at this point in the history
  • Loading branch information
zcbenz committed Jul 9, 2024
1 parent a063c65 commit 4e9761d
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 9 deletions.
15 changes: 10 additions & 5 deletions src/instance_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,21 @@ class InstanceData {
return true;
}

// DeleteWeakRef returns false if there is no weak ref existing for ptr, which
// would only happen when user has removed the weak ref manually.
template<typename T>
void DeleteWeakRef(void* ptr) {
bool DeleteWeakRef(void* ptr) {
WeakRefKey key{internal::TopClass<T>::name, ptr};
auto it = weak_refs_.find(key);
if (it == weak_refs_.end()) {
assert(false);
return;
}
if (it == weak_refs_.end())
return false;
if (--it->second.first == 0)
weak_refs_.erase(it);
return true;
}

size_t WeakRefsSize() const {
return weak_refs_.size();
}

private:
Expand Down
7 changes: 5 additions & 2 deletions src/prototype.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@ napi_status ManagePointerInJSWrapper(napi_env env, T* ptr, napi_value* result) {
using DataType = decltype(data);
napi_status s = napi_wrap(env, object, data,
[](napi_env env, void* data, void* ptr) {
if (internal::CanCachePointer<T>::value)
InstanceData::Get(env)->DeleteWeakRef<T>(ptr);
if (internal::CanCachePointer<T>::value) {
// If the weak ref has already been removed, do not run finalizer.
if (!InstanceData::Get(env)->DeleteWeakRef<T>(ptr))
return;
}
internal::Finalize<T>::Do(static_cast<DataType>(data));
}, ptr, nullptr);
if (s != napi_ok) {
Expand Down
7 changes: 5 additions & 2 deletions src/prototype_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,11 @@ struct DefineClass<T, typename std::enable_if<is_function_pointer<
using DataType = decltype(data);
napi_status s = napi_wrap(env, object, data,
[](napi_env env, void* data, void* ptr) {
if (internal::CanCachePointer<T>::value)
InstanceData::Get(env)->DeleteWeakRef<T>(ptr);
if (internal::CanCachePointer<T>::value) {
// If the weak ref has already been removed, do not run finalizer.
if (!InstanceData::Get(env)->DeleteWeakRef<T>(ptr))
return;
}
Finalize<T>::Do(static_cast<DataType>(data));
Destruct<T>::Do(static_cast<T*>(ptr));
}, ptr.value(), nullptr);
Expand Down

0 comments on commit 4e9761d

Please sign in to comment.