[gjs/ewlsh/fix-closures] Test memory handling



commit dc84bf06169e6d2ef42f61488f0e5c0f7834cce9
Author: Evan Welsh <contact evanwelsh com>
Date:   Sat Jan 15 13:26:50 2022 -0800

    Test memory handling

 gi/closure.h   | 37 +++++++++++++++++++++++++------------
 gi/object.cpp  |  2 +-
 gi/private.cpp |  4 +++-
 3 files changed, 29 insertions(+), 14 deletions(-)
---
diff --git a/gi/closure.h b/gi/closure.h
index 551939d5..98ca9712 100644
--- a/gi/closure.h
+++ b/gi/closure.h
@@ -78,18 +78,6 @@ class Closure : public GClosure {
         return self;
     }
 
-    [[nodiscard]] static Closure* create_for_signal(JSContext* cx,
-                                                    JSFunction* callable,
-                                                    const char* description,
-                                                    unsigned signal_id) {
-        auto* self = new Closure(cx, callable, false /* root */, description);
-        self->add_finalize_notifier<Closure>();
-        SignalClosureMeta* meta = new SignalClosureMeta();
-        meta->signal_id = signal_id;
-        g_closure_set_meta_marshal(self, meta, marshal_cb);
-        return self;
-    }
-
     constexpr JSFunction* callable() const { return m_func; }
     [[nodiscard]] constexpr JSContext* context() const { return m_cx; }
     [[nodiscard]] constexpr bool is_valid() const { return !!m_cx; }
@@ -111,6 +99,7 @@ class Closure : public GClosure {
         m_cx = nullptr;
     }
 
+ protected:
     static void marshal_cb(GClosure* closure, GValue* ret, unsigned n_params,
                            const GValue* params, void* hint, void* data) {
         for_gclosure(closure)->marshal(ret, n_params, params, hint, data);
@@ -134,6 +123,30 @@ class Closure : public GClosure {
     GjsMaybeOwned<JSFunction*> m_func;
 };
 
+class SignalClosure : public Closure {
+ protected:
+    SignalClosureMeta m_meta;
+
+    SignalClosure(JSContext* cx, JSFunction* func, const char* description,
+                  unsigned signal_id)
+        : Closure(cx, func, false, description) {
+        m_meta.signal_id = signal_id;
+
+        g_closure_set_meta_marshal(this, &m_meta, marshal_cb);
+    }
+
+ public:
+    [[nodiscard]] static SignalClosure* create(JSContext* cx,
+                                               JSFunction* callable,
+                                               const char* description,
+                                               unsigned signal_id) {
+        auto* self = new SignalClosure(cx, callable, description, signal_id);
+
+        self->add_finalize_notifier<SignalClosure>();
+        return self;
+    }
+};
+
 }  // namespace Gjs
 
 #endif  // GI_CLOSURE_H_
diff --git a/gi/object.cpp b/gi/object.cpp
index d1880966..80a5acac 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -2141,7 +2141,7 @@ ObjectInstance::connect_impl(JSContext          *context,
         return false;
     }
 
-    GClosure* closure = Gjs::Closure::create_for_signal(
+    GClosure* closure = Gjs::SignalClosure::create(
         context, JS_GetObjectFunction(callback), "signal callback", signal_id);
     if (closure == NULL)
         return false;
diff --git a/gi/private.cpp b/gi/private.cpp
index 1fc13935..c4e25df1 100644
--- a/gi/private.cpp
+++ b/gi/private.cpp
@@ -282,6 +282,8 @@ static bool gjs_create_closure(JSContext* cx, unsigned argc, JS::Value* vp) {
     if (closure == nullptr)
         return false;
 
+    g_closure_ref(closure);
+    g_closure_sink(closure);
     return gjs_value_from_closure(cx, closure, args.rval());
 }
 
@@ -314,7 +316,7 @@ static bool gjs_create_signal_closure(JSContext* cx, unsigned argc,
 
     JS::RootedFunction func(cx, JS_GetObjectFunction(callable));
 
-    Gjs::Closure* closure = Gjs::Closure::create_for_signal(
+    Gjs::Closure* closure = Gjs::SignalClosure::create(
         cx, func, "custom signal callback", signal_id);
 
     if (closure == nullptr)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]