From 69fd1fd1d0f110800ec713bac5dafb418ceecc1c Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Sun, 9 Nov 2014 11:22:42 -0500 Subject: [PATCH] GClosure: add valgrind hints GClosure has been in the "allocate area before the pointer" game since before we did this with GTypeInstance. At the time that this was done for GClosure, we didn't have valgrind.h in GLib. Now that we do, we should add similar valgrind hints as the ones we did for GTypeInstance. This substantially reduces reports of "possibly lost" on pretty much any program that makes use of signals. https://bugzilla.gnome.org/show_bug.cgi?id=739850 --- gobject/gclosure.c | 43 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/gobject/gclosure.c b/gobject/gclosure.c index 33353bb..014e40a 100644 --- a/gobject/gclosure.c +++ b/gobject/gclosure.c @@ -22,6 +22,7 @@ #include "config.h" +#include "../glib/valgrind.h" #include #include @@ -189,14 +190,31 @@ GClosure* g_closure_new_simple (guint sizeof_closure, gpointer data) { - GRealClosure *real_closure; GClosure *closure; + gint private_size; + gchar *allocated; g_return_val_if_fail (sizeof_closure >= sizeof (GClosure), NULL); - sizeof_closure = sizeof_closure + sizeof (GRealClosure) - sizeof (GClosure); - real_closure = g_malloc0 (sizeof_closure); - closure = &real_closure->closure; + private_size = sizeof (GRealClosure) - sizeof (GClosure); + + /* See comments in gtype.c about what's going on here... */ + if (RUNNING_ON_VALGRIND) + { + private_size += sizeof (gpointer); + + allocated = g_malloc0 (private_size + sizeof_closure + sizeof (gpointer)); + + *(gpointer *) (allocated + private_size + sizeof_closure) = allocated + sizeof (gpointer); + + VALGRIND_MALLOCLIKE_BLOCK (allocated + private_size, sizeof_closure + sizeof (gpointer), 0, TRUE); + VALGRIND_MALLOCLIKE_BLOCK (allocated + sizeof (gpointer), private_size - sizeof (gpointer), 0, TRUE); + } + else + allocated = g_malloc0 (private_size + sizeof_closure); + + closure = (GClosure *) (allocated + private_size); + SET (closure, ref_count, 1); SET (closure, floating, TRUE); closure->data = data; @@ -589,7 +607,22 @@ g_closure_unref (GClosure *closure) { closure_invoke_notifiers (closure, FNOTIFY); g_free (closure->notifiers); - g_free (G_REAL_CLOSURE (closure)); + + /* See comments in gtype.c about what's going on here... */ + if (RUNNING_ON_VALGRIND) + { + gchar *allocated; + + allocated = (gchar *) G_REAL_CLOSURE (closure); + allocated -= sizeof (gpointer); + + g_free (allocated); + + VALGRIND_FREELIKE_BLOCK (allocated + sizeof (gpointer), 0); + VALGRIND_FREELIKE_BLOCK (closure, 0); + } + else + g_free (G_REAL_CLOSURE (closure)); } } -- 2.7.4