[glib/wip/gcleanup: 6/7] Make some use of G_CLEANUP_ADD
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/wip/gcleanup: 6/7] Make some use of G_CLEANUP_ADD
- Date: Mon, 25 Mar 2013 01:58:46 +0000 (UTC)
commit 4dbc4727afe2684a4f4b9cd3a6a1a37af12c4e89
Author: Ryan Lortie <desrt desrt ca>
Date: Sun Mar 24 16:14:03 2013 -0400
Make some use of G_CLEANUP_ADD
This is enough to get a few testcases running with zero memory in use at
the end.
glib/gcharset.c | 9 +++++++-
glib/gcleanup.c | 3 ++
glib/gconvert.c | 2 +
glib/gmain.c | 31 ++++++++++++++++++++++++--
glib/grand.c | 6 ++++-
glib/gslice.c | 2 +
glib/gtestutils.c | 31 +++++++++++++++++++++++++++
glib/gthread.c | 2 +
glib/gutils.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++-------
9 files changed, 134 insertions(+), 13 deletions(-)
---
diff --git a/glib/gcharset.c b/glib/gcharset.c
index 3fca455..4661b0f 100644
--- a/glib/gcharset.c
+++ b/glib/gcharset.c
@@ -28,6 +28,7 @@
#include "gmessages.h"
#include "gstrfuncs.h"
#include "gthread.h"
+#include "gcleanup.h"
#ifdef G_OS_WIN32
#include "gwin32.h"
#endif
@@ -186,6 +187,7 @@ g_get_charset (const char **charset)
if (!cache)
{
cache = g_new0 (GCharsetCache, 1);
+ G_CLEANUP_ADD (&cache_private, g_private_reset);
g_private_set (&cache_private, cache);
}
@@ -240,7 +242,11 @@ read_aliases (gchar *file)
char buf[256];
if (!alias_table)
- alias_table = g_hash_table_new (g_str_hash, g_str_equal);
+ {
+ alias_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ G_CLEANUP_ADD (alias_table, g_hash_table_unref);
+ }
+
fp = fopen (file,"r");
if (!fp)
return;
@@ -560,6 +566,7 @@ g_get_language_names (void)
if (!cache)
{
cache = g_new0 (GLanguageNamesCache, 1);
+ G_CLEANUP_ADD (&cache_private, g_private_reset);
g_private_set (&cache_private, cache);
}
diff --git a/glib/gcleanup.c b/glib/gcleanup.c
index a65ca1a..92fb632 100644
--- a/glib/gcleanup.c
+++ b/glib/gcleanup.c
@@ -26,6 +26,9 @@
#include <stdlib.h>
+/* As good a place as any to put this... */
+G_CLEANUP_DEFINE
+
typedef struct _GCleanupNode GCleanupNode;
struct _GCleanupNode
{
diff --git a/glib/gconvert.c b/glib/gconvert.c
index 3320a5e..350cb0c 100644
--- a/glib/gconvert.c
+++ b/glib/gconvert.c
@@ -50,6 +50,7 @@
#include "gthread.h"
#include "gunicode.h"
#include "gfileutils.h"
+#include "gcleanup.h"
#ifdef NEED_ICONV_CACHE
#include "glist.h"
@@ -1321,6 +1322,7 @@ g_get_filename_charsets (const gchar ***filename_charsets)
if (!cache)
{
cache = g_new0 (GFilenameCharsetCache, 1);
+ G_CLEANUP_ADD (&cache_private, g_private_reset);
g_private_set (&cache_private, cache);
}
diff --git a/glib/gmain.c b/glib/gmain.c
index 68a7f8e..24676ab 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -100,6 +100,7 @@
#include "gmain-internal.h"
#include "glib-init.h"
#include "glib-private.h"
+#include "gcleanup.h"
/**
* SECTION:main
@@ -410,7 +411,9 @@ static gboolean g_idle_dispatch (GSource *source,
static void block_source (GSource *source);
+static GThread *glib_worker_thread;
static GMainContext *glib_worker_context;
+static gboolean glib_worker_quit_requested;
G_LOCK_DEFINE_STATIC (main_loop);
static GMainContext *default_main_context;
@@ -648,6 +651,7 @@ g_main_context_default (void)
if (_g_main_poll_debug)
g_print ("default context=%p\n", default_main_context);
#endif
+ G_CLEANUP_ADD (default_main_context, g_main_context_unref);
}
G_UNLOCK (main_loop);
@@ -2703,6 +2707,7 @@ get_dispatch (void)
if (!dispatch)
{
dispatch = g_slice_new0 (GMainDispatch);
+ G_CLEANUP_ADD (&depth_private, g_private_reset);
g_private_set (&depth_private, dispatch);
}
@@ -5422,7 +5427,7 @@ g_main_context_invoke_full (GMainContext *context,
static gpointer
glib_worker_main (gpointer data)
{
- while (TRUE)
+ while (!glib_worker_quit_requested)
{
g_main_context_iteration (glib_worker_context, TRUE);
@@ -5432,7 +5437,24 @@ glib_worker_main (gpointer data)
#endif
}
- return NULL; /* worst GCC warning message ever... */
+ return NULL;
+}
+
+static gboolean
+return_false (gpointer user_data)
+{
+ return FALSE;
+}
+
+static void
+glib_worker_kill (void)
+{
+ glib_worker_quit_requested = TRUE;
+ g_main_context_invoke (glib_worker_context, return_false, NULL);
+ g_thread_join (glib_worker_thread);
+ glib_worker_thread = NULL;
+ g_main_context_unref (glib_worker_context);
+ glib_worker_context = NULL;
}
GMainContext *
@@ -5451,10 +5473,13 @@ g_get_worker_context (void)
pthread_sigmask (SIG_SETMASK, &all, &prev_mask);
#endif
glib_worker_context = g_main_context_new ();
- g_thread_new ("gmain", glib_worker_main, NULL);
+ glib_worker_thread = g_thread_new ("gmain", glib_worker_main, NULL);
#ifdef G_OS_UNIX
pthread_sigmask (SIG_SETMASK, &prev_mask, NULL);
#endif
+
+ G_CLEANUP_ADD_FUNC (glib_worker_kill);
+
g_once_init_leave (&initialised, TRUE);
}
diff --git a/glib/grand.c b/glib/grand.c
index 6bd7f18..049299f 100644
--- a/glib/grand.c
+++ b/glib/grand.c
@@ -54,6 +54,7 @@
#include "gmem.h"
#include "gtestutils.h"
#include "gthread.h"
+#include "gcleanup.h"
#ifdef G_OS_WIN32
#include <process.h> /* For getpid() */
@@ -590,7 +591,10 @@ get_global_random (void)
/* called while locked */
if (!global_random)
- global_random = g_rand_new ();
+ {
+ global_random = g_rand_new ();
+ G_CLEANUP_ADD (global_random, g_rand_free);
+ }
return global_random;
}
diff --git a/glib/gslice.c b/glib/gslice.c
index b1c499b..dd2c743 100644
--- a/glib/gslice.c
+++ b/glib/gslice.c
@@ -52,6 +52,7 @@
#include "gtestutils.h"
#include "gthread.h"
#include "glib_trace.h"
+#include "gcleanup.h"
/**
* SECTION:memory_slices
@@ -510,6 +511,7 @@ thread_memory_from_self (void)
tmem = g_malloc0 (sizeof (ThreadMemory) + sizeof (Magazine) * 2 * n_magazines);
tmem->magazine1 = (Magazine*) (tmem + 1);
tmem->magazine2 = &tmem->magazine1[n_magazines];
+ G_CLEANUP_ADD (&private_thread_memory, g_private_reset);
g_private_set (&private_thread_memory, tmem);
}
return tmem;
diff --git a/glib/gtestutils.c b/glib/gtestutils.c
index 4089758..158e7d6 100644
--- a/glib/gtestutils.c
+++ b/glib/gtestutils.c
@@ -836,6 +836,35 @@ parse_args (gint *argc_p,
*argc_p = e;
}
+static void
+g_test_case_free (GTestCase *test_case)
+{
+ g_free (test_case->name);
+ g_slice_free (GTestCase, test_case);
+}
+
+static void
+g_test_suite_free (GTestSuite *suite)
+{
+ g_free (suite->name);
+ g_slist_free_full (suite->suites, (GDestroyNotify) g_test_suite_free);
+ g_slist_free_full (suite->cases, (GDestroyNotify) g_test_case_free);
+ g_slice_free (GTestSuite, suite);
+}
+
+static void
+g_test_cleanup (void)
+{
+ g_clear_pointer (&test_run_rand, g_rand_free);
+
+ if (test_suite_root)
+ g_test_suite_free (test_suite_root);
+
+ g_free (test_trap_last_stdout);
+ g_free (test_trap_last_stderr);
+ g_free (test_uri_base);
+}
+
/**
* g_test_init:
* @argc: Address of the @argc parameter of the main() function.
@@ -973,6 +1002,8 @@ g_test_init (int *argc,
/* report program start */
g_log_set_default_handler (gtest_default_log_handler, NULL);
g_test_log (G_TEST_LOG_START_BINARY, g_get_prgname(), test_run_seedstr, 0, NULL);
+
+ G_CLEANUP_ADD_FUNC (g_test_cleanup);
}
static void
diff --git a/glib/gthread.c b/glib/gthread.c
index c27bca6..98cd3b7 100644
--- a/glib/gthread.c
+++ b/glib/gthread.c
@@ -59,6 +59,7 @@
#include "gslice.h"
#include "gstrfuncs.h"
#include "gtestutils.h"
+#include "gcleanup.h"
/**
* SECTION:threads
@@ -1001,6 +1002,7 @@ g_thread_self (void)
thread = g_slice_new0 (GRealThread);
thread->ref_count = 1;
+ G_CLEANUP_ADD (&g_thread_specific_private, g_private_reset);
g_private_set (&g_thread_specific_private, thread);
}
diff --git a/glib/gutils.c b/glib/gutils.c
index 76f6c34..772df2f 100644
--- a/glib/gutils.c
+++ b/glib/gutils.c
@@ -797,6 +797,10 @@ g_get_user_database_entry (void)
if (!e.real_name)
e.real_name = g_strdup ("Unknown");
+ G_CLEANUP_ADD (e.user_name, g_free);
+ G_CLEANUP_ADD (e.real_name, g_free);
+ G_CLEANUP_ADD (e.home_dir, g_free);
+
g_once_init_leave (&entry, &e);
}
@@ -944,6 +948,11 @@ g_get_home_dir (void)
*/
tmp = entry->home_dir;
}
+ else
+ /* Only free this during cleanup if it's not from the user
+ * entry, because the user entry does its own freeing...
+ */
+ G_CLEANUP_ADD (tmp, g_free);
g_once_init_leave (&home_dir, tmp);
}
@@ -1013,6 +1022,8 @@ g_get_tmp_dir (void)
}
#endif /* !G_OS_WIN32 */
+ G_CLEANUP_ADD (tmp, g_free);
+
g_once_init_leave (&tmp_dir, tmp);
}
@@ -1048,6 +1059,7 @@ g_get_host_name (void)
{
gboolean failed;
gchar tmp[100];
+ gchar *result;
#ifndef G_OS_WIN32
failed = (gethostname (tmp, sizeof (tmp)) == -1);
@@ -1056,7 +1068,10 @@ g_get_host_name (void)
failed = (!GetComputerName (tmp, &size));
#endif
- g_once_init_leave (&hostname, g_strdup (failed ? "localhost" : tmp));
+ result = g_strdup (failed ? "localhost" : tmp);
+ G_CLEANUP_ADD (result, g_free);
+
+ g_once_init_leave (&hostname, result);
}
return hostname;
@@ -1101,6 +1116,7 @@ g_get_prgname (void)
if (utf8_buf)
{
g_prgname = g_path_get_basename (utf8_buf);
+ G_CLEANUP_ADD (g_prgname, g_free);
g_free (utf8_buf);
}
}
@@ -1116,16 +1132,26 @@ g_get_prgname (void)
* g_set_prgname:
* @prgname: the name of the program.
*
- * Sets the name of the program. This name should <emphasis>not</emphasis>
- * be localized, contrast with g_set_application_name(). Note that for
- * thread-safety reasons this function can only be called once.
+ * Sets the name of the program. This name should <emphasis>not</emphasis>
+ * be localized, contrast with g_set_application_name(). Note that for
+ * thread-safety reasons if this function is called more than once or is
+ * called after g_get_prgname() has been called, memory will be leaked.
*/
void
g_set_prgname (const gchar *prgname)
{
G_LOCK (g_prgname);
- g_free (g_prgname);
+ /* We want to use remove here because this is a leak and we want that
+ * to show up in valgrind, so we should _not_ free the original string
+ * during cleanup.
+ */
+ if (g_prgname)
+ {
+ G_CLEANUP_REMOVE (g_prgname, g_free);
+ g_free (g_prgname);
+ }
g_prgname = g_strdup (prgname);
+ G_CLEANUP_ADD (g_prgname, g_free);
G_UNLOCK (g_prgname);
}
@@ -1189,7 +1215,10 @@ g_set_application_name (const gchar *application_name)
if (g_application_name)
already_set = TRUE;
else
- g_application_name = g_strdup (application_name);
+ {
+ g_application_name = g_strdup (application_name);
+ G_CLEANUP_ADD (g_application_name, g_free);
+ }
G_UNLOCK (g_application_name);
if (already_set)
@@ -1243,6 +1272,7 @@ g_get_user_data_dir (void)
data_dir = g_build_filename (g_get_tmp_dir (), g_get_user_name (), ".local", "share", NULL);
}
+ G_CLEANUP_ADD (data_dir, g_free);
g_user_data_dir = data_dir;
}
else
@@ -1278,6 +1308,7 @@ g_init_user_config_dir (void)
config_dir = g_build_filename (g_get_tmp_dir (), g_get_user_name (), ".config", NULL);
}
+ G_CLEANUP_ADD (config_dir, g_free);
g_user_config_dir = config_dir;
}
}
@@ -1360,6 +1391,7 @@ g_get_user_cache_dir (void)
else
cache_dir = g_build_filename (g_get_tmp_dir (), g_get_user_name (), ".cache", NULL);
}
+ G_CLEANUP_ADD (cache_dir, g_free);
g_user_cache_dir = cache_dir;
}
else
@@ -1396,13 +1428,14 @@ const gchar *
g_get_user_runtime_dir (void)
{
#ifndef G_OS_WIN32
- static const gchar *runtime_dir;
+ static gchar *runtime_dir;
static gsize initialised;
if (g_once_init_enter (&initialised))
{
runtime_dir = g_strdup (getenv ("XDG_RUNTIME_DIR"));
-
+ if (runtime_dir)
+ G_CLEANUP_ADD (runtime_dir, g_free);
g_once_init_leave (&initialised, 1);
}
@@ -1757,6 +1790,17 @@ g_reload_user_special_dirs_cache (void)
G_UNLOCK (g_utils_global);
}
+static void
+cleanup_user_special_dirs (void)
+{
+ gint i;
+
+ for (i = 0; i < G_USER_N_DIRECTORIES; i++)
+ g_free (g_user_special_dirs[i]);
+
+ g_free (g_user_special_dirs);
+}
+
/**
* g_get_user_special_dir:
* @directory: the logical id of special directory
@@ -1789,6 +1833,7 @@ g_get_user_special_dir (GUserDirectory directory)
if (G_UNLIKELY (g_user_special_dirs == NULL))
{
g_user_special_dirs = g_new0 (gchar *, G_USER_N_DIRECTORIES);
+ G_CLEANUP_ADD_FUNC (cleanup_user_special_dirs);
load_user_special_dirs ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]