[gjs: 1/3] object: Fix GjsCallBackTrampoline's leaks
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs: 1/3] object: Fix GjsCallBackTrampoline's leaks
- Date: Thu, 3 Sep 2020 21:03:24 +0000 (UTC)
commit 0ca5c00ded5505cb8a88bb06b1c7673f0f327b41
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date: Wed Sep 2 18:33:59 2020 +0200
object: Fix GjsCallBackTrampoline's leaks
Each time we initialize a trampoline for vfunc implementation we never
unref the memory it allocates, this was not noticed so far as GSlice
seems to have confused the sanitizer.
To avoid this, let's add a further invalidation notifier where we unref
the trampoline once the closure has been invalidated.
As per this, when manually invalidating the closure, let's add a
temporary reference so that we can safely unref it again in the
invalidation notify function without risks of acting on the last
reference of the closure itself.
gi/object.cpp | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
---
diff --git a/gi/object.cpp b/gi/object.cpp
index c8fcad746..1fb8c99e5 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -1450,8 +1450,12 @@ static void invalidate_closure_list(std::forward_list<GClosure*>* closures) {
// invalidate notifier
while (!closures->empty()) {
// This will also free the closure data, through the closure
- // invalidation mechanism
- GClosure* closure = *closures->begin();
+ // invalidation mechanism, but adding a temporary reference to
+ // ensure that the closure is still valid when calling invalidation
+ // notify callbacks
+ using GjsAutoGClosure =
+ GjsAutoPointer<GClosure, GClosure, g_closure_unref, g_closure_ref>;
+ GjsAutoGClosure closure(closures->front(), GjsAutoTakeOwnership());
g_closure_invalidate(closure);
/* Erase element if not already erased */
closures->remove(closure);
@@ -2618,6 +2622,11 @@ bool ObjectPrototype::hook_up_vfunc_impl(JSContext* cx,
g_closure_add_invalidate_notifier(
trampoline->js_function, this,
&ObjectPrototype::vfunc_invalidated_notify);
+ g_closure_add_invalidate_notifier(
+ trampoline->js_function, trampoline, [](void* data, GClosure*) {
+ auto* trampoline = static_cast<GjsCallbackTrampoline*>(data);
+ gjs_callback_trampoline_unref(trampoline);
+ });
*((ffi_closure **)method_ptr) = trampoline->closure;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]