From 239ba9864e96ee90e75943fef432bcbe98a01904 Mon Sep 17 00:00:00 2001 From: Ceri Coburn Date: Thu, 9 Oct 2014 21:42:50 +0100 Subject: [PATCH 1/2] Hook g_object_newv instead of g_object_new to prevent missing some GObjects --- gobject-list.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/gobject-list.c b/gobject-list.c index cd41a6d..e1a057f 100644 --- a/gobject-list.c +++ b/gobject-list.c @@ -329,20 +329,18 @@ _object_finalized (gpointer data, } gpointer -g_object_new (GType type, - const char *first, - ...) +g_object_newv (GType object_type, + guint n_parameters, + GParameter *parameters) { - gpointer (* real_g_object_new_valist) (GType, const char *, va_list); - va_list var_args; + gpointer (* real_g_object_newv) (GType object_type,guint n_parameters,GParameter *parameters); + GObject *obj; const char *obj_name; - real_g_object_new_valist = get_func ("g_object_new_valist"); + real_g_object_newv = get_func ("g_object_newv"); - va_start (var_args, first); - obj = real_g_object_new_valist (type, first, var_args); - va_end (var_args); + obj = real_g_object_newv (object_type, n_parameters, parameters); obj_name = G_OBJECT_TYPE_NAME (obj); From 5dca5084fcdfaf902a10496e9f4dd6b9d65affeb Mon Sep 17 00:00:00 2001 From: Ceri Coburn Date: Fri, 10 Oct 2014 08:38:09 +0100 Subject: [PATCH 2/2] g_object_new, g_object_newv and g_object_new_valist need to be hooked to prevent missed objects --- gobject-list.c | 119 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 79 insertions(+), 40 deletions(-) diff --git a/gobject-list.c b/gobject-list.c index e1a057f..d6b3d75 100644 --- a/gobject-list.c +++ b/gobject-list.c @@ -328,59 +328,98 @@ _object_finalized (gpointer data, G_UNLOCK (gobject_list); } -gpointer -g_object_newv (GType object_type, - guint n_parameters, - GParameter *parameters) +static void +_track_object(GObject* obj) { - gpointer (* real_g_object_newv) (GType object_type,guint n_parameters,GParameter *parameters); + const char* obj_name = G_OBJECT_TYPE_NAME (obj); + + G_LOCK (gobject_list); + + if (g_hash_table_lookup (gobject_list_state.objects, obj) == NULL && + object_filter (obj_name)) + { + if (display_filter (DISPLAY_FLAG_CREATE)) + { + g_print (" ++ Created object %p, %s\n", obj, obj_name); + print_trace(); + } + + /* FIXME: For thread safety, GWeakRef should be used here, except it + * won’t give us notify callbacks. Perhaps an opportunistic combination + * of GWeakRef and g_object_weak_ref() — the former for safety, the latter + * for notifications (with the knowledge that due to races, some + * notifications may get omitted)? + * + * Alternatively, we could abuse GToggleRef. Inadvisable because other + * code could be using it. + * + * Alternatively, we could switch to a garbage-collection style of + * working, where gobject-list runs in its own thread and uses GWeakRefs + * to keep track of objects. Periodically, it would check the hash table + * and notify of which references have been nullified. */ + g_object_weak_ref (obj, _object_finalized, NULL); + + g_hash_table_insert (gobject_list_state.objects, obj, + GUINT_TO_POINTER (TRUE)); + g_hash_table_insert (gobject_list_state.added, obj, + GUINT_TO_POINTER (TRUE)); + } + + G_UNLOCK (gobject_list); +} - GObject *obj; - const char *obj_name; +GObject* +g_object_new_valist (GType type, + const gchar *first, + va_list var_args) +{ - real_g_object_newv = get_func ("g_object_newv"); + gpointer (*real_g_object_new_valist) (GType, const char *, va_list); + GObject *obj; - obj = real_g_object_newv (object_type, n_parameters, parameters); + real_g_object_new_valist = get_func ("g_object_new_valist"); - obj_name = G_OBJECT_TYPE_NAME (obj); + obj = (GObject*)real_g_object_new_valist (type, first, var_args); - G_LOCK (gobject_list); + _track_object(obj); + return obj; +} - if (g_hash_table_lookup (gobject_list_state.objects, obj) == NULL && - object_filter (obj_name)) - { - if (display_filter (DISPLAY_FLAG_CREATE)) - { - g_print (" ++ Created object %p, %s\n", obj, obj_name); - print_trace(); - } +gpointer +g_object_new (GType type, + const char *first, + ...) +{ - /* FIXME: For thread safety, GWeakRef should be used here, except it - * won’t give us notify callbacks. Perhaps an opportunistic combination - * of GWeakRef and g_object_weak_ref() — the former for safety, the latter - * for notifications (with the knowledge that due to races, some - * notifications may get omitted)? - * - * Alternatively, we could abuse GToggleRef. Inadvisable because other - * code could be using it. - * - * Alternatively, we could switch to a garbage-collection style of - * working, where gobject-list runs in its own thread and uses GWeakRefs - * to keep track of objects. Periodically, it would check the hash table - * and notify of which references have been nullified. */ - g_object_weak_ref (obj, _object_finalized, NULL); - - g_hash_table_insert (gobject_list_state.objects, obj, - GUINT_TO_POINTER (TRUE)); - g_hash_table_insert (gobject_list_state.added, obj, - GUINT_TO_POINTER (TRUE)); - } + gpointer (*real_g_object_new_valist) (GType, const char *, va_list); + va_list var_args; + GObject *obj; - G_UNLOCK (gobject_list); + real_g_object_new_valist = get_func ("g_object_new_valist"); + va_start (var_args, first); + obj = (GObject*)real_g_object_new_valist (type, first, var_args); + va_end (var_args); + + _track_object(obj); return obj; } +gpointer +g_object_newv (GType object_type, + guint n_parameters, + GParameter *parameters) +{ + GObject *obj; + gpointer (*real_g_object_newv )(GType object_type, guint n_parameters,GParameter *parameters); + + real_g_object_newv = get_func ("g_object_newv"); + + obj = (GObject*)real_g_object_newv(object_type,n_parameters,parameters); + _track_object(obj); + return obj; +} + gpointer g_object_ref (gpointer object) {