[gjs] Synchronously process all idle object toggle references on context dispose



commit 59009aed2ff0342b1715f3a927bedbb205829cad
Author: Colin Walters <walters verbum org>
Date:   Sat Apr 6 12:23:39 2013 -0400

    Synchronously process all idle object toggle references on context dispose
    
    Fixes the test suite.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=697436

 gi/object.c   |   15 +++++++++++++++
 gi/object.h   |    2 ++
 gjs/context.c |   11 +++++++++++
 3 files changed, 28 insertions(+), 0 deletions(-)
---
diff --git a/gi/object.c b/gi/object.c
index 5c399a2..585a3ba 100644
--- a/gi/object.c
+++ b/gi/object.c
@@ -88,6 +88,7 @@ enum {
 
 static struct JSClass gjs_object_instance_class;
 static GThread *gjs_eval_thread;
+static volatile gint pending_idle_toggles;
 
 GJS_DEFINE_PRIV_FROM_JS(ObjectInstance, gjs_object_instance_class)
 
@@ -968,6 +969,7 @@ toggle_ref_notify_operation_free(ToggleRefNotifyOperation *operation)
     if (operation->needs_unref)
         g_object_unref (operation->gobj);
     g_slice_free(ToggleRefNotifyOperation, operation);
+    g_atomic_int_add(&pending_idle_toggles, -1);
 }
 
 static void
@@ -1017,6 +1019,7 @@ queue_toggle_idle(GObject         *gobj,
                           operation,
                           (GDestroyNotify) toggle_ref_notify_operation_free);
 
+    g_atomic_int_inc(&pending_idle_toggles);
     g_object_set_qdata (gobj, qdata_key, source);
     g_source_attach (source, NULL);
 
@@ -1100,6 +1103,18 @@ wrapped_gobj_toggle_notify(gpointer      data,
         gjs_unblock_gc();
 }
 
+/* At shutdown, we need to ensure we've cleared the context of any
+ * pending toggle references.
+ */
+void
+gjs_object_process_pending_toggles (void)
+{
+    while (g_main_context_pending (NULL) &&
+           g_atomic_int_get (&pending_idle_toggles) > 0) {
+        g_main_context_iteration (NULL, FALSE);
+    }
+}
+
 static ObjectInstance *
 init_object_private (JSContext *context,
                      JSObject  *object)
diff --git a/gi/object.h b/gi/object.h
index a494946..145139c 100644
--- a/gi/object.h
+++ b/gi/object.h
@@ -46,6 +46,8 @@ JSBool    gjs_typecheck_object          (JSContext     *context,
                                          GType          expected_type,
                                          JSBool         throw);
 
+void      gjs_object_process_pending_toggles (void);
+
 G_END_DECLS
 
 #endif  /* __GJS_OBJECT_H__ */
diff --git a/gjs/context.c b/gjs/context.c
index 3d48594..fa55f63 100644
--- a/gjs/context.c
+++ b/gjs/context.c
@@ -32,6 +32,7 @@
 #include "compat.h"
 
 #include "gi.h"
+#include "gi/object.h"
 
 #include <modules/modules.h>
 
@@ -383,6 +384,16 @@ gjs_context_dispose(GObject *object)
         gjs_debug(GJS_DEBUG_CONTEXT,
                   "Destroying JS context");
 
+        gjs_object_process_pending_toggles();
+
+        /* Do a full GC here before tearing down, since once we do
+         * that we may not have the JS_GetPrivate() to access the
+         * context
+         */
+        JS_GC(js_context->runtime);
+
+        gjs_object_process_pending_toggles();
+
         JS_DestroyContext(js_context->context);
         js_context->context = NULL;
     }


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