[glib: 1/3] gthread: Add g_private_set_alloc0() internal convenience API
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 1/3] gthread: Add g_private_set_alloc0() internal convenience API
- Date: Mon, 7 Jan 2019 19:35:39 +0000 (UTC)
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]