[glib/wip/gcleanup: 8/10] Make some use of G_CLEANUP_ADD



commit 09492e3a38b3f10a884f9251e7b4af3d62c8e8ee
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 bb8c044..013b8be 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 fd8f04e..74284fe 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"
 
 #include "glibintl.h"
 
@@ -1023,6 +1024,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 98603f7..21ca883 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;
@@ -653,6 +656,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);
@@ -2717,6 +2721,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);
     }
 
@@ -5469,7 +5474,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);
 
@@ -5479,7 +5484,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 *
@@ -5498,10 +5520,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 3f043ad..b7d241c 100644
--- a/glib/grand.c
+++ b/glib/grand.c
@@ -55,6 +55,7 @@
 #include "gmem.h"
 #include "gtestutils.h"
 #include "gthread.h"
+#include "gcleanup.h"
 
 #ifdef G_OS_WIN32
 #include <stdlib.h>
@@ -603,7 +604,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 7a8268b..b252806 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"
 
 #include "valgrind.h"
 
@@ -523,6 +524,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 353a2db..c8c0f82 100644
--- a/glib/gtestutils.c
+++ b/glib/gtestutils.c
@@ -999,6 +999,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.
@@ -1157,6 +1186,8 @@ g_test_init (int    *argc,
   test_built_files_dir = g_getenv ("G_TEST_BUILDDIR");
   if (!test_built_files_dir)
     test_built_files_dir = test_argv0_dirname;
+
+  G_CLEANUP_ADD_FUNC (g_test_cleanup);
 }
 
 static void
diff --git a/glib/gthread.c b/glib/gthread.c
index c4114aa..be9f74b 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
@@ -1002,6 +1003,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 3485ec2..6c8ff2e 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);
     }
@@ -1009,6 +1018,8 @@ g_get_tmp_dir (void)
         }
 #endif /* !G_OS_WIN32 */
 
+      G_CLEANUP_ADD (tmp, g_free);
+
       g_once_init_leave (&tmp_dir, tmp);
     }
 
@@ -1044,6 +1055,7 @@ g_get_host_name (void)
     {
       gboolean failed;
       gchar tmp[100];
+      gchar *result;
 
 #ifndef G_OS_WIN32
       failed = (gethostname (tmp, sizeof (tmp)) == -1);
@@ -1052,7 +1064,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;
@@ -1097,6 +1112,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);
            }
        }
@@ -1112,16 +1128,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);
 }
 
@@ -1185,7 +1211,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)
@@ -1239,6 +1268,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
@@ -1274,6 +1304,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;
     }
 }
@@ -1356,6 +1387,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
@@ -1392,13 +1424,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);
     }
 
@@ -1752,6 +1785,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
@@ -1784,6 +1828,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]