summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2013-04-06 12:23:39 -0400
committerColin Walters <walters@verbum.org>2013-04-22 11:10:06 -0400
commit3f445d8bc155d7aafe75e73f9592257aecae44da (patch)
tree1980c0477a443d50a7f300f4699d1da557bedef8
parent1fd25f05b91b0d347b9289a07140592d24ca5013 (diff)
downloadgjs-3f445d8bc155d7aafe75e73f9592257aecae44da.tar.gz
Synchronously process all idle object toggle references on context dispose
Fixes the test suite. https://bugzilla.gnome.org/show_bug.cgi?id=697436
-rw-r--r--gi/object.c15
-rw-r--r--gi/object.h2
-rw-r--r--gjs/context.c11
3 files changed, 28 insertions, 0 deletions
diff --git a/gi/object.c b/gi/object.c
index 68f80912..c56f195f 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 a494946d..145139cd 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 90c5afbf..113d84af 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->context);
+
+ gjs_object_process_pending_toggles();
+
JS_DestroyContext(js_context->context);
js_context->context = NULL;
}