[glib/wip/gcleanup: 6/7] Make some use of G_CLEANUP_ADD



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]