[glib: 1/3] gthread: Add g_private_set_alloc0() internal convenience API



commit f6caeb6d1abe94926a49fde6ffc1d4254b308b2a
Author: Philip Withnall <withnall endlessm com>
Date:   Thu Dec 6 15:16:33 2018 +0000

    gthread: Add g_private_set_alloc0() internal convenience API
    
    This is a wrapper around g_private_set() which allocates the desired
    amount of memory for the caller and calls g_private_set() on it.
    
    This is intended to make it easier to suppress Valgrind warnings about
    leaked memory, since g_private_set() is typically used to make one-time
    per-thread allocations. We can now just add a blanket suppression rule
    for any allocations inside g_private_set_alloc0().
    
    Signed-off-by: Philip Withnall <withnall endlessm com>

 glib.supp             |  9 +++++++++
 glib/gcharset.c       |  6 ++----
 glib/gconvert.c       |  6 ++----
 glib/gmain.c          |  8 +++-----
 glib/gslice.c         |  4 ++--
 glib/gthread.c        | 27 +++++++++++++++++++++++++++
 glib/gthreadprivate.h |  3 +++
 7 files changed, 48 insertions(+), 15 deletions(-)
---
diff --git a/glib.supp b/glib.supp
index c8b184e5c..7b8478803 100644
--- a/glib.supp
+++ b/glib.supp
@@ -656,4 +656,13 @@
        ...
        fun:g_dbus_error_register_error_domain
        fun:g_dbus_error_quark
+}
+
+# Thread-private data allocated once per thread
+{
+       g_private_set_alloc0
+       Memcheck:Leak
+       fun:malloc
+       ...
+       fun:g_private_set_alloc0
 }
\ No newline at end of file
diff --git a/glib/gcharset.c b/glib/gcharset.c
index a97b33a03..8f4f03946 100644
--- a/glib/gcharset.c
+++ b/glib/gcharset.c
@@ -27,6 +27,7 @@
 #include "gmessages.h"
 #include "gstrfuncs.h"
 #include "gthread.h"
+#include "gthreadprivate.h"
 #ifdef G_OS_WIN32
 #include "gwin32.h"
 #endif
@@ -187,10 +188,7 @@ g_get_charset (const char **charset)
   const gchar *raw;
 
   if (!cache)
-    {
-      cache = g_new0 (GCharsetCache, 1);
-      g_private_set (&cache_private, cache);
-    }
+    cache = g_private_set_alloc0 (&cache_private, sizeof (GCharsetCache));
 
   G_LOCK (aliases);
   raw = _g_locale_charset_raw ();
diff --git a/glib/gconvert.c b/glib/gconvert.c
index 3f6621b2a..707867951 100644
--- a/glib/gconvert.c
+++ b/glib/gconvert.c
@@ -46,6 +46,7 @@
 #include "gstrfuncs.h"
 #include "gtestutils.h"
 #include "gthread.h"
+#include "gthreadprivate.h"
 #include "gunicode.h"
 #include "gfileutils.h"
 
@@ -1131,10 +1132,7 @@ g_get_filename_charsets (const gchar ***filename_charsets)
   const gchar *charset;
 
   if (!cache)
-    {
-      cache = g_new0 (GFilenameCharsetCache, 1);
-      g_private_set (&cache_private, cache);
-    }
+    cache = g_private_set_alloc0 (&cache_private, sizeof (GFilenameCharsetCache));
 
   g_get_charset (&charset);
 
diff --git a/glib/gmain.c b/glib/gmain.c
index c24690e44..83e398cfa 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -87,6 +87,7 @@
 #include "gqueue.h"
 #include "gstrfuncs.h"
 #include "gtestutils.h"
+#include "gthreadprivate.h"
 
 #ifdef G_OS_WIN32
 #include "gwin32.h"
@@ -2828,7 +2829,7 @@ g_get_monotonic_time (void)
 static void
 g_main_dispatch_free (gpointer dispatch)
 {
-  g_slice_free (GMainDispatch, dispatch);
+  g_free (dispatch);
 }
 
 /* Running the main loop */
@@ -2842,10 +2843,7 @@ get_dispatch (void)
   dispatch = g_private_get (&depth_private);
 
   if (!dispatch)
-    {
-      dispatch = g_slice_new0 (GMainDispatch);
-      g_private_set (&depth_private, dispatch);
-    }
+    dispatch = g_private_set_alloc0 (&depth_private, sizeof (GMainDispatch));
 
   return dispatch;
 }
diff --git a/glib/gslice.c b/glib/gslice.c
index d1b1fc639..86e76cec0 100644
--- a/glib/gslice.c
+++ b/glib/gslice.c
@@ -45,6 +45,7 @@
 #include "gtrashstack.h"
 #include "gtestutils.h"
 #include "gthread.h"
+#include "gthreadprivate.h"
 #include "glib_trace.h"
 #include "gprintf.h"
 
@@ -515,10 +516,9 @@ thread_memory_from_self (void)
       g_mutex_unlock (&init_mutex);
 
       n_magazines = MAX_SLAB_INDEX (allocator);
-      tmem = g_malloc0 (sizeof (ThreadMemory) + sizeof (Magazine) * 2 * n_magazines);
+      tmem = g_private_set_alloc0 (&private_thread_memory, sizeof (ThreadMemory) + sizeof (Magazine) * 2 * 
n_magazines);
       tmem->magazine1 = (Magazine*) (tmem + 1);
       tmem->magazine2 = &tmem->magazine1[n_magazines];
-      g_private_set (&private_thread_memory, tmem);
     }
   return tmem;
 }
diff --git a/glib/gthread.c b/glib/gthread.c
index 69010f978..2b7be91dd 100644
--- a/glib/gthread.c
+++ b/glib/gthread.c
@@ -517,6 +517,33 @@ static GPrivate     g_thread_specific_private = G_PRIVATE_INIT (g_thread_cleanup
 
 G_LOCK_DEFINE_STATIC (g_thread_new);
 
+/*
+ * g_private_set_alloc0:
+ * @key: a #GPrivate
+ * @size: size of the allocation, in bytes
+ *
+ * Sets the thread local variable @key to have a newly-allocated and zero-filled
+ * value of given @size, and returns a pointer to that memory. Allocations made
+ * using this API will be suppressed in valgrind: it is intended to be used for
+ * one-time allocations which are known to be leaked, such as those for
+ * per-thread initialisation data. Otherwise, this function behaves the same as
+ * g_private_set().
+ *
+ * Returns: (transfer full): new thread-local heap allocation of size @size
+ * Since: 2.60
+ */
+/*< private >*/
+gpointer
+g_private_set_alloc0 (GPrivate *key,
+                      gsize     size)
+{
+  gpointer allocated = g_malloc0 (size);
+
+  g_private_set (key, allocated);
+
+  return g_steal_pointer (&allocated);
+}
+
 /* GOnce {{{1 ------------------------------------------------------------- */
 
 /**
diff --git a/glib/gthreadprivate.h b/glib/gthreadprivate.h
index 2cf8bdc00..75bb3cbf2 100644
--- a/glib/gthreadprivate.h
+++ b/glib/gthreadprivate.h
@@ -56,4 +56,7 @@ GThread *       g_thread_new_internal           (const gchar  *name,
 
 gpointer        g_thread_proxy                  (gpointer      thread);
 
+gpointer        g_private_set_alloc0            (GPrivate       *key,
+                                                 gsize           size);
+
 #endif /* __G_THREADPRIVATE_H__ */


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