[glib/wip/gcleanup: 15/78] Make some use of G_CLEANUP_ADD



commit 8d73d0672caf66fe8e424fb1c9e26fbc0ae17cf4
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.
    
    Tweaked by: Stef Walter <stefw redhat com>
    
    https://bugzilla.gnome.org/show_bug.cgi?id=711744

 glib/Makefile.am  |    1 +
 glib/gcharset.c   |    7 +++++-
 glib/gconvert.c   |    1 +
 glib/gmain.c      |   24 +++++++++++++++++--
 glib/grand.c      |    6 ++++-
 glib/gslice.c     |    1 +
 glib/gtestutils.c |   31 ++++++++++++++++++++++++++
 glib/gthread.c    |    1 +
 glib/gutils.c     |   63 +++++++++++++++++++++++++++++++++++++++++++++++------
 9 files changed, 123 insertions(+), 12 deletions(-)
---
diff --git a/glib/Makefile.am b/glib/Makefile.am
index 9c3c19e..ec506cc 100644
--- a/glib/Makefile.am
+++ b/glib/Makefile.am
@@ -38,6 +38,7 @@ AM_CPPFLAGS =                                 \
        $(glib_INCLUDES)                \
        $(pcre_inc)                     \
        -DG_LOG_DOMAIN=\"GLib\"         \
+       -DG_CLEANUP_SCOPE=glib_cleanup  \
        $(GLIB_DEBUG_FLAGS)             \
        -DGLIB_COMPILATION              \
        -DPCRE_STATIC
diff --git a/glib/gcharset.c b/glib/gcharset.c
index bb8c044..cdbc357 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
@@ -240,7 +241,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 (alias_table, g_hash_table_unref);
+    }
+
   fp = fopen (file,"r");
   if (!fp)
     return;
diff --git a/glib/gconvert.c b/glib/gconvert.c
index fd8f04e..0382eed 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"
 
diff --git a/glib/gmain.c b/glib/gmain.c
index 608c1a5..5f16f6d 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 gint          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 (default_main_context, g_main_context_unref);
     }
 
   G_UNLOCK (main_loop);
@@ -5471,7 +5475,7 @@ g_main_context_invoke_full (GMainContext   *context,
 static gpointer
 glib_worker_main (gpointer data)
 {
-  while (TRUE)
+  while (!g_atomic_int_get (&glib_worker_quit_requested))
     {
       g_main_context_iteration (glib_worker_context, TRUE);
 
@@ -5481,7 +5485,18 @@ glib_worker_main (gpointer data)
 #endif
     }
 
-  return NULL; /* worst GCC warning message ever... */
+  return NULL;
+}
+
+static void
+glib_worker_kill (void)
+{
+  g_atomic_int_set (&glib_worker_quit_requested, 1);
+  g_main_context_wakeup (glib_worker_context);
+  g_thread_join (glib_worker_thread);
+  glib_worker_thread = NULL;
+  g_main_context_unref (glib_worker_context);
+  glib_worker_context = NULL;
 }
 
 GMainContext *
@@ -5500,10 +5515,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_FUNC (glib_worker_kill);
+
       g_once_init_leave (&initialised, TRUE);
     }
 
diff --git a/glib/grand.c b/glib/grand.c
index 3f043ad..ab74983 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 (global_random, g_rand_free);
+    }
 
   return global_random;
 }
diff --git a/glib/gslice.c b/glib/gslice.c
index 7a8268b..7bd8218 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"
 
diff --git a/glib/gtestutils.c b/glib/gtestutils.c
index 353a2db..43bee66 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_FUNC (g_test_cleanup);
 }
 
 static void
diff --git a/glib/gthread.c b/glib/gthread.c
index c4114aa..141ab7e 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
diff --git a/glib/gutils.c b/glib/gutils.c
index 3485ec2..7235bed 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 (e.user_name, g_free);
+      G_CLEANUP (e.real_name, g_free);
+      G_CLEANUP (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 (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 (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 (result, g_free);
+
+      g_once_init_leave (&hostname, result);
     }
 
   return hostname;
@@ -1061,6 +1076,13 @@ g_get_host_name (void)
 G_LOCK_DEFINE_STATIC (g_prgname);
 static gchar *g_prgname = NULL;
 
+static void
+cleanup_prgname (void)
+{
+  g_free (g_prgname);
+  g_prgname = NULL;
+}
+
 /**
  * g_get_prgname:
  *
@@ -1097,6 +1119,7 @@ g_get_prgname (void)
          if (utf8_buf)
            {
              g_prgname = g_path_get_basename (utf8_buf);
+              G_CLEANUP_FUNC (cleanup_prgname);
              g_free (utf8_buf);
            }
        }
@@ -1112,14 +1135,21 @@ 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);
+  /* 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_FUNC (cleanup_prgname);
   g_free (g_prgname);
   g_prgname = g_strdup (prgname);
   G_UNLOCK (g_prgname);
@@ -1185,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 (g_application_name, g_free);
+    }
   G_UNLOCK (g_application_name);
 
   if (already_set)
@@ -1239,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 (data_dir, g_free);
       g_user_data_dir = data_dir;
     }
   else
@@ -1274,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 (config_dir, g_free);
       g_user_config_dir = config_dir;
     }
 }
@@ -1356,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 (cache_dir, g_free);
       g_user_cache_dir = cache_dir;
     }
   else
@@ -1392,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 (runtime_dir, g_free);
       g_once_init_leave (&initialised, 1);
     }
 
@@ -1752,6 +1789,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 +1832,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_FUNC (cleanup_user_special_dirs);
 
       load_user_special_dirs ();
 


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