[seed] engine: Don't call JSValueUnprotect() from the finalizer of the object



commit a015bdb33c3bdd7f250a842c7be8062d483598b8
Author: Sebastian Dröge <sebastian centricular com>
Date:   Thu Jan 8 10:20:46 2015 +0100

    engine: Don't call JSValueUnprotect() from the finalizer of the object
    
    JSValueUnprotect() would be called from g_object_set_data_full() via the
    destroy notify we set for the data before. Steal the qdata instead as this
    won't call the destroy notify, and we don't have to clean up anything here.
    
    We would not get here at all anyway if the object still had a "protect count"
    higher than 0, as that would prevent the GC from cleaning up the object.
    
    Also the docs say:
    
    You must not call any function that may cause a garbage collection or an allocation
    of a garbage collected object from within a JSObjectFinalizeCallback. This includes
    all functions that have a JSContextRef parameter.
    
    Also consistently use the qdata variants of the functions instead of the data
    variants that take a string instead of a quark.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=742574

 libseed/seed-engine.c |    9 +++++++--
 libseed/seed-types.c  |    2 +-
 2 files changed, 8 insertions(+), 3 deletions(-)
---
diff --git a/libseed/seed-engine.c b/libseed/seed-engine.c
index 12e3358..226ea64 100644
--- a/libseed/seed-engine.c
+++ b/libseed/seed-engine.c
@@ -1169,10 +1169,15 @@ seed_gobject_finalize (JSObjectRef object)
             g_type_name (G_OBJECT_TYPE (gobject)), gobject,
             gobject->ref_count);
 
-  js_ref = g_object_get_data (gobject, "js-ref");
+  js_ref = g_object_get_qdata (gobject, js_ref_quark);
   if (js_ref)
     {
-      g_object_set_data_full (gobject, "js-ref", NULL, NULL);
+      /* Steal the qdata here as otherwise we will call
+       * JSValueUnprotect() from the destroy notify of
+       * the qdata, which is not allowed to be called
+       * from a finalizer!
+       */
+      g_object_steal_qdata (gobject, js_ref_quark);
 
       g_object_remove_toggle_ref (gobject, seed_toggle_ref, js_ref);
     }
diff --git a/libseed/seed-types.c b/libseed/seed-types.c
index 76b94a3..d0c6281 100644
--- a/libseed/seed-types.c
+++ b/libseed/seed-types.c
@@ -42,7 +42,7 @@ seed_toggle_ref (gpointer data, GObject * object, gboolean is_last_ref)
 {
   JSValueRef wrapper;
 
-  if (!g_object_get_data (object, "js-ref"))
+  if (!g_object_get_qdata (object, js_ref_quark))
     return;
 
   wrapper = (JSValueRef) data;


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