fix(napi): prevent memory leak when Custom GC is used (#1963)

There is a piece of custom logic that has been added a while back to ensure
that Buffers can be sent across threads, and be dropped properly. This involves
a custom GC that runs on NodeJS's current thread (per my understanding). The
logic to drop the buffer on that custom GC differed from the one in the Drop
impl. This meant that everytime Node sent a buffer back to a napi-rs function,
the reference wouldn't be cleaned up properly, and it would leak (96 bytes per
Reference on an ARM MacOS machine).

This commit updates the logic in the custom GC so that it matches the one in
the Drop impl. This worked locally, and fixed any occurence of the leak I could
find.
This commit is contained in:
Louis 2024-02-20 13:36:21 +01:00 committed by GitHub
parent 90e3a349db
commit 9391196eef
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -619,10 +619,19 @@ extern "C" fn custom_gc(
if THREADS_CAN_ACCESS_ENV.borrow_mut(|m| m.get(&std::thread::current().id()) == Some(&false)) {
return;
}
let mut reference = 0;
let mut ref_count = 0;
check_status_or_throw!(
env,
unsafe { sys::napi_reference_unref(env, data.cast(), &mut reference) },
unsafe { sys::napi_reference_unref(env, data.cast(), &mut ref_count) },
"Failed to unref Buffer reference in Custom GC"
);
debug_assert!(
ref_count == 0,
"Buffer reference count in Custom GC is not 0"
);
check_status_or_throw!(
env,
unsafe { sys::napi_delete_reference(env, data.cast()) },
"Failed to delete Buffer reference in Custom GC"
);
}