[glib/wip/gcleanup] gcleanup: Rework cleanup mechanism again, in particular we need remove



commit c82ff6dc9f4af319481a1a518169cb7fe9ac9e93
Author: Stef Walter <stefw gnome org>
Date:   Fri Nov 8 22:41:37 2013 +0100

    gcleanup: Rework cleanup mechanism again, in particular we need remove
    
    Make remove very fast, and possible during cleanup. Any use of remove
    can be short circuited during cleanup.
    
    Subsequent cleanup add tries to use same discarded entry removed earlier
    but only if not during cleanup.

 gio/giomodule.c                      |    6 +-
 glib/deprecated/gthread-deprecated.c |    2 +-
 glib/gcleanup.c                      |  283 ++++++++++++++++++---------------
 glib/gcleanup.h                      |   51 ++++---
 glib/gthread-posix.c                 |   12 +-
 glib/gthread.h                       |    2 +-
 gobject/gbinding.c                   |    2 +-
 gobject/gboxed.c                     |    4 +-
 gobject/genums.c                     |    4 +-
 gobject/gobject.c                    |    4 +-
 gobject/gparam.c                     |    4 +-
 gobject/gparamspecs.c                |    2 +-
 gobject/gsignal.c                    |    2 +-
 gobject/gsourceclosure.c             |    2 +-
 gobject/gtype.c                      |   14 +-
 gobject/gtype.h                      |   12 +-
 gobject/gtypemodule.c                |    2 +-
 gobject/gtypemodule.h                |    2 +-
 gobject/gtypeplugin.c                |    2 +-
 gobject/gvaluetypes.c                |   28 ++--
 gobject/tests/dynamictests.c         |    2 +-
 gobject/tests/enums.c                |    4 +-
 gobject/tests/signals.c              |    8 +-
 gobject/tests/testcommon.h           |    4 +-
 gobject/tests/type.c                 |    2 +-
 25 files changed, 245 insertions(+), 215 deletions(-)
---
diff --git a/gio/giomodule.c b/gio/giomodule.c
index 78d8511..876ef99 100644
--- a/gio/giomodule.c
+++ b/gio/giomodule.c
@@ -694,7 +694,7 @@ _g_io_module_get_default_type (const gchar *extension_point,
   else
     {
       default_modules = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-      g_cleanup_list_push (G_CLEANUP_LIST, (GCleanupFunc)g_hash_table_unref, default_modules,
+      g_cleanup_list_push (G_CLEANUP_LOCAL, (GCleanupFunc)g_hash_table_unref, default_modules,
                            G_CLEANUP_PHASE_EARLY, NULL);
     }
 
@@ -821,7 +821,7 @@ _g_io_module_get_default (const gchar         *extension_point,
     {
       default_modules = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                g_free, g_object_unref);
-      g_cleanup_list_push (G_CLEANUP_LIST, (GCleanupFunc)g_hash_table_unref, default_modules,
+      g_cleanup_list_push (G_CLEANUP_LOCAL, (GCleanupFunc)g_hash_table_unref, default_modules,
                            G_CLEANUP_PHASE_EARLY, NULL);
     }
 
@@ -1139,7 +1139,7 @@ g_io_extension_point_register (const char *name)
     {
       extension_points = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
                                                 (GDestroyNotify)g_io_extension_point_free);
-      g_cleanup_list_push (G_CLEANUP_LIST, (GCleanupFunc)g_hash_table_unref, extension_points,
+      g_cleanup_list_push (G_CLEANUP_LOCAL, (GCleanupFunc)g_hash_table_unref, extension_points,
                            G_CLEANUP_PHASE_EARLY, NULL);
     }
 
diff --git a/glib/deprecated/gthread-deprecated.c b/glib/deprecated/gthread-deprecated.c
index 906f72c..7fd40b3 100644
--- a/glib/deprecated/gthread-deprecated.c
+++ b/glib/deprecated/gthread-deprecated.c
@@ -1466,7 +1466,7 @@ g_static_private_free (GStaticPrivate *private_key)
   if (!cleanup_pushed)
     {
       cleanup_pushed = TRUE;
-      g_cleanup_list_push (G_CLEANUP_LIST, (GCleanupFunc)cleanup_free_indices,
+      g_cleanup_list_push (G_CLEANUP_LOCAL, (GCleanupFunc)cleanup_free_indices,
                            NULL, G_CLEANUP_PHASE_GRAVEYARD, "cleanup_free_indices");
     }
   g_thread_free_indices = g_slist_prepend (g_thread_free_indices,
diff --git a/glib/gcleanup.c b/glib/gcleanup.c
index 0a42aa5..27081c4 100644
--- a/glib/gcleanup.c
+++ b/glib/gcleanup.c
@@ -25,6 +25,7 @@
 
 #include "glib-init.h"
 #include "gatomic.h"
+#include "gbitlock.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -38,56 +39,31 @@
 
 #include <stdio.h>
 
-#define MAX_PASSES 3
-
 /* As good a place as any to put this... */
 G_CLEANUP_DEFINE
 
 typedef struct _GCleanupNode GCleanupNode;
 struct _GCleanupNode
 {
-  GDestroyNotify  func;
+  GDestroyNotify  func;         /* If NULL, then node is removed */
   gpointer        data;
-  GCleanupPhase   phase;
+  gint            phase;
   const gchar    *location;
   GCleanupNode   *next;
 };
 
-/* indexes into list->priv */
-enum {
-  P_NODES = 0,
-  P_LOG = 1,
-};
-
-/* indexes into list->vals */
-enum {
-  V_FLAGS = 0,
-  V_PHASE = 1,
-};
-
-static const gchar *
-phase_to_string (GCleanupPhase phase)
-{
-  switch (phase)
-  {
-    case G_CLEANUP_PHASE_EARLY:
-      return "early";
-    case G_CLEANUP_PHASE_MAIN:
-      return "main";
-    case G_CLEANUP_PHASE_LATE:
-      return "late";
-    case G_CLEANUP_PHASE_GRAVEYARD:
-      return "graveyard";
-    default:
-      return "unknown";
-  }
-}
+typedef struct {
+  gint flags;
+  gint lock;
+  gint removed;
+  GCleanupNode *nodes;
+} GRealCleanup;
 
 static gboolean
-check_if_verbose (const gchar *log_domain)
+check_if_verbose (void)
 {
   const gchar *env = getenv ("G_MESSAGES_DEBUG");
-  return (env && (strcmp (env, "all") == 0 || strstr (env, log_domain)));
+  return (env && strcmp (env, "all") == 0);
 }
 
 /**
@@ -132,92 +108,104 @@ g_cleanup_is_enabled (void)
  * list at the same time.
  *
  * Since: 2.40
+ *
+ * Returns: an item which can be passed to g_cleanup_list_remove() to remove
+ *          the cleanup function
  **/
-void
+gpointer
 g_cleanup_list_push (GCleanupList *list,
                      GCleanupFunc  cleanup_func,
                      gpointer      user_data,
-                     GCleanupPhase phase,
+                     gint          phase,
                      const gchar  *location)
 {
+  GRealCleanup *cleanup;
   GCleanupNode *node;
-  const gchar *log_domain;
-
-  g_return_if_fail (cleanup_func != NULL);
+  GCleanupNode **ptr;
 
   if (!list || !g_cleanup_enabled)
-    return;
+    return NULL;
 
-  g_return_if_fail (phase >= g_atomic_int_get (&list->vals[V_PHASE]));
+  cleanup = (GRealCleanup *)list;
+  node = NULL;
 
-  node = malloc (sizeof (GCleanupNode));
-  node->func = cleanup_func;
-  node->data = user_data;
-  node->location = location;
-  node->phase = phase;
+  g_bit_lock (&cleanup->lock, 1);
 
-  do
+  /* If there's a removed item, try to use it */
+  if (cleanup->removed > 0)
     {
-      node->next = list->priv[P_NODES];
+      for (ptr = &cleanup->nodes; (node = *ptr) != NULL; ptr = &(*ptr)->next)
+        {
+          /* If the node->func is NULL, steal the node */
+          if (node->func == NULL)
+            {
+              *ptr = node->next;
+              cleanup->removed--;
+              break;
+            }
+        }
     }
-  while (!g_atomic_pointer_compare_and_exchange (&list->priv[P_NODES],
-                                                 node->next, node));
 
-  log_domain = list->priv[P_LOG];
-  if (check_if_verbose (log_domain))
+  /* Allocate a new one */
+  if (node == NULL)
+      node = malloc (sizeof (GCleanupNode));
+
+  if (node != NULL)
     {
-      fprintf (stderr, "%s-DEBUG: g_cleanup_list_push: pushed %p/%s at %s\n",
-               log_domain, user_data, phase_to_string (phase), location);
+      node->func = cleanup_func;
+      node->data = user_data;
+      node->location = location;
+      node->phase = phase;
+
+      node->next = cleanup->nodes;
+      cleanup->nodes = node;
+    }
+
+  g_bit_unlock (&cleanup->lock, 1);
+
+  if (check_if_verbose ())
+    {
+      fprintf (stderr, "GCleanup-DEBUG: g_cleanup_list_push: pushed %p/%d at %s\n",
+               user_data, phase, location);
     }
+
+  return node;
 }
 
-static GCleanupNode *
-cleanup_pass (GCleanupNode *clear,
-              GCleanupNode *also,
-              GCleanupPhase phase,
-              gboolean verbose,
-              const gchar *log_domain,
-              gboolean *cleaned_up)
+/**
+ * g_cleanup_list_remove:
+ * @list: a #GCleanupList
+ * @item: the cleanup item
+ *
+ * Removes an @item in the list.
+ *
+ * This function reverses a previous call to g_cleanup_list_add(), and takes
+ * the item pointer returned by g_cleanup_list_add().
+ *
+ * This function is threadsafe.  Changes can occur while adds and
+ * changes are occuring in other threads.
+ *
+ * Since: 2.40
+**/
+void
+g_cleanup_list_remove (GCleanupList *list,
+                       gpointer      tag)
 {
-  GCleanupNode *later;
-  GCleanupNode **later_next;
+  GRealCleanup *cleanup;
   GCleanupNode *node;
 
-  later = NULL;
-  later_next = &later;
-
-  while (clear || also)
-    {
-      if (!clear && also)
-        {
-          clear = also;
-          also = NULL;
-        }
+  if (!tag || !list || !g_cleanup_enabled)
+    return;
 
-      node = clear;
-      clear = node->next;
+  cleanup = (GRealCleanup *)list;
+  node = tag;
 
-      if (node->phase > phase)
-        {
-          node->next = NULL;
-          *later_next = node;
-          later_next = &node->next;
-        }
-      else
-        {
-          if (verbose)
-            {
-              fprintf (stderr, "%s-DEBUG: g_cleanup_list_clear: cleanup at %s: %p at %s\n",
-                       log_domain, phase_to_string (node->phase), node->data, node->location);
-            }
+  g_bit_lock (&cleanup->lock, 1);
 
-          (*node->func) (node->data);
-          *cleaned_up = TRUE;
-          free (node);
-        }
-    }
+  cleanup->removed++;
+  g_atomic_pointer_set (&node->func, NULL);
 
-  return later;
+  g_bit_unlock (&cleanup->lock, 1);
 }
 
 /**
@@ -232,67 +220,104 @@ cleanup_pass (GCleanupNode *clear,
  * emit a destructor function to call this when your library or program
  * is being unloaded.
  *
+ * This function is threadsafe.  Changes can occur while adds and
+ * changes are occuring in other threads.
+ *
  * Since: 2.40
  **/
 void
 g_cleanup_list_clear (GCleanupList *list)
 {
+  GRealCleanup *cleanup;
   GCleanupNode *later;
-  GCleanupNode *clear;
-  GCleanupPhase phase;
-  gboolean progressed;
-  const gchar *log_domain;
+  GCleanupNode *nodes;
+  GCleanupNode *node;
+  GCleanupNode **last;
+  GCleanupFunc func;
   gboolean verbose;
-  gint i;
+  gint phase;
+  gint next;
 
   if (!list || !g_cleanup_enabled)
     return;
 
-  log_domain = list->priv[P_LOG];
-  verbose = check_if_verbose (log_domain);
-
-  /* Note that we're starting to clear */
-  phase = G_CLEANUP_PHASE_EARLY;
-  if (!g_atomic_int_compare_and_exchange (&list->vals[V_PHASE], 0, phase))
-    {
-      fprintf (stderr, "%s-CRITICAL: g_cleanup_list_clear() called twice for the same GCleanupList\n",
-               log_domain);
-      return;
-    }
+  verbose = check_if_verbose ();
+  cleanup = (GRealCleanup *)list;
 
   later = NULL;
+  nodes = NULL;
+  phase = 0;
+  next = 0;
 
-  while (phase <= G_CLEANUP_PHASE_GRAVEYARD)
+  do
     {
-      for (i = 0; i < MAX_PASSES + 1; i++)
+      later = nodes;
+
+      g_bit_lock (&cleanup->lock, 1);
+
+      nodes = cleanup->nodes;
+      cleanup->nodes = NULL;
+
+      g_bit_unlock (&cleanup->lock, 1);
+
+      /* The next phase we were going to run */
+      phase = next;
+
+      /* No next phase yet */
+      next = G_MAXINT;
+
+      /* Find a lower phase, and find last */
+      last = &nodes;
+      for (node = nodes; node; node = node->next)
         {
-          progressed = FALSE;
+          if (node->phase < phase)
+            phase = node->phase;
+          last = &node->next;
+        }
+
+      /* Join the two lists */
+      *last = later;
+
+      /* Run that phase */
+      for (node = nodes; node; node = node->next)
+        {
+          func = g_atomic_pointer_get (&node->func);
+          if (!func)
+            continue;
 
-          do
+          /* Part of this phase */
+          if (phase == node->phase)
             {
-              /* Steal the list pointer */
-              clear = list->priv[P_NODES];
+              if (g_atomic_pointer_compare_and_exchange (&node->func, func, NULL))
+                {
+                  if (verbose)
+                    {
+                      fprintf (stderr, "GCleanup-DEBUG: g_cleanup_list_clear: cleanup at %d: %p at %s\n",
+                               phase, node->data, node->location);
+                    }
+                  (func) (node->data);
+                }
             }
-          while (!g_atomic_pointer_compare_and_exchange (&list->priv[P_NODES], clear, NULL));
 
-          if (clear && i == MAX_PASSES)
+          /* Find the next phase */
+          else if (node->phase > phase && node->phase < next)
             {
-              fprintf (stderr, "%s-WARNING: g_cleanup_list_clear: gave up after %d passes\n",
-                       log_domain, MAX_PASSES);
-              return;
+              next = node->phase;
             }
-
-          later = cleanup_pass (later, clear, phase, verbose, log_domain, &progressed);
-
-          if (!progressed)
-            break;
         }
+    }
+  while (next != G_MAXINT);
 
-      phase = g_atomic_int_add (&list->vals[V_PHASE], 1) + 1;
+  /* Free all the nodes */
+  while (nodes)
+    {
+      node = nodes;
+      nodes = node->next;
+      free (node);
     }
 
   if (verbose)
-    fprintf (stderr, "%s-DEBUG: g_cleanup_list_clear: cleanup done\n", log_domain);
+    fprintf (stderr, "GCleanup-DEBUG: g_cleanup_list_clear: cleanup done\n");
 }
 
 /**
diff --git a/glib/gcleanup.h b/glib/gcleanup.h
index 5f7b85e..8337be1 100644
--- a/glib/gcleanup.h
+++ b/glib/gcleanup.h
@@ -31,75 +31,78 @@
 
 G_BEGIN_DECLS
 
+enum {
+  G_CLEANUP_PHASE_EARLY = -50,
+  G_CLEANUP_PHASE_DEFAULT = 0,
+  G_CLEANUP_PHASE_LATE = 50,
+  G_CLEANUP_PHASE_GRAVEYARD = 100,
+};
+
 typedef struct
 {
+  /*< private >*/
+  gint value;
   gpointer priv[4];
-  gint     vals[4];
 } GCleanupList;
 
-typedef enum
-{
-  G_CLEANUP_PHASE_EARLY = 1,
-  G_CLEANUP_PHASE_MAIN = 2,
-  G_CLEANUP_PHASE_LATE = 3,
-  G_CLEANUP_PHASE_GRAVEYARD = 4,
-} GCleanupPhase;
-
 typedef void (* GCleanupFunc) (gpointer user_data);
 
 GLIB_AVAILABLE_IN_2_40
 gboolean                g_cleanup_is_enabled                            (void);
 GLIB_AVAILABLE_IN_2_40
-void                    g_cleanup_list_push                             (GCleanupList *list,
+gpointer                g_cleanup_list_push                             (GCleanupList *list,
                                                                          GCleanupFunc  cleanup_func,
                                                                          gpointer      user_data,
-                                                                         GCleanupPhase phase,
+                                                                         gint          phase,
                                                                          const gchar  *location);
 GLIB_AVAILABLE_IN_2_40
+void                    g_cleanup_list_remove                           (GCleanupList *list,
+                                                                         gpointer      tag);
+GLIB_AVAILABLE_IN_2_40
 void                    g_cleanup_list_clear                            (GCleanupList *list);
 
 #if defined(G_HAS_CONSTRUCTORS) && !defined(G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA) && defined(G_CLEANUP_MODULE)
 
 extern GCleanupList G_PASTE(G_CLEANUP_MODULE, _cleanup_list);
 
-#define G_CLEANUP_LIST                                                          \
+#define G_CLEANUP_LOCAL                                                         \
   (&G_PASTE (G_CLEANUP_MODULE, _cleanup_list))
 #define G_CLEANUP_DEFINE \
   GCleanupList G_PASTE(G_CLEANUP_MODULE, _cleanup_list) =                       \
-    { { 0, G_LOG_DOMAIN,  }, { 0, } };                                          \
+    { 0, { 0, }, };                                                             \
   G_DEFINE_DESTRUCTOR (G_PASTE (G_CLEANUP_MODULE, _cleanup_perform))            \
   static void G_PASTE (G_CLEANUP_MODULE, _cleanup_perform) (void) {             \
-    g_cleanup_list_clear (G_CLEANUP_LIST);                                      \
+    g_cleanup_list_clear (G_CLEANUP_LOCAL);                                     \
   }
 #define G_CLEANUP(data, func) \
   G_STMT_START {                                                                \
     if (0) (func) ((data));                                                     \
-    g_cleanup_list_push (G_CLEANUP_LIST, (void*) (func), (data),                 \
-                         G_CLEANUP_PHASE_MAIN, G_STRLOC ": " G_STRINGIFY (func)); \
+    g_cleanup_list_push (G_CLEANUP_LOCAL, (void*) (func), (data),               \
+                         G_CLEANUP_PHASE_DEFAULT, G_STRINGIFY (func));          \
   } G_STMT_END
 #define G_CLEANUP_LATE(data, func) \
   G_STMT_START {                                                                \
     if (0) (func) ((data));                                                     \
-    g_cleanup_list_push (G_CLEANUP_LIST, (void*) (func), (data),                 \
-                         G_CLEANUP_PHASE_LATE, G_STRLOC ": " G_STRINGIFY (func));\
+    g_cleanup_list_push (G_CLEANUP_LOCAL, (void*) (func), (data),               \
+                         G_CLEANUP_PHASE_LATE, G_STRINGIFY (func));             \
   } G_STMT_END
 #define G_CLEANUP_FUNC(func) \
   G_STMT_START {                                                                \
     if (0) (func) ();                                                           \
-    g_cleanup_list_push (G_CLEANUP_LIST, (void*) (func), NULL,                   \
-                         G_CLEANUP_PHASE_MAIN, G_STRLOC ": " G_STRINGIFY (func)); \
+    g_cleanup_list_push (G_CLEANUP_LOCAL, (void*) (func), NULL,                 \
+                         G_CLEANUP_PHASE_DEFAULT, G_STRINGIFY (func));          \
   } G_STMT_END
 #define G_CLEANUP_LATE_FUNC(func) \
   G_STMT_START {                                                                \
     if (0) (func) ();                                                           \
-    g_cleanup_list_push (G_CLEANUP_LIST, (void*) (func), NULL,                   \
-                         G_CLEANUP_PHASE_LATE, G_STRLOC ": " G_STRINGIFY (func));\
+    g_cleanup_list_push (G_CLEANUP_LOCAL, (void*) (func), NULL,                 \
+                         G_CLEANUP_PHASE_LATE, G_STRINGIFY (func));             \
   } G_STMT_END
 
 #else
 
-#define G_CLEANUP_LIST    NULL
-#define G_CLEANUP_DEFINE(flags)
+#define G_CLEANUP_LOCAL    NULL
+#define G_CLEANUP_DEFINE
 #define G_CLEANUP(data, func) \
   G_STMT_START {                                                        \
     if (0) (func) (data);                                               \
diff --git a/glib/gthread-posix.c b/glib/gthread-posix.c
index c367eb3..51bce89 100644
--- a/glib/gthread-posix.c
+++ b/glib/gthread-posix.c
@@ -128,7 +128,7 @@ g_mutex_get_impl (GMutex *mutex)
     {
       impl = g_mutex_impl_new ();
       if (g_atomic_pointer_compare_and_exchange (&mutex->p, NULL, impl))
-        g_cleanup_list_push (G_CLEANUP_LIST, (GCleanupFunc)g_mutex_impl_free, impl,
+        g_cleanup_list_push (G_CLEANUP_LOCAL, (GCleanupFunc)g_mutex_impl_free, impl,
                              G_CLEANUP_PHASE_GRAVEYARD, G_STRFUNC);
       else
         g_mutex_impl_free (impl);
@@ -303,7 +303,7 @@ g_rec_mutex_get_impl (GRecMutex *rec_mutex)
     {
       impl = g_rec_mutex_impl_new ();
       if (g_atomic_pointer_compare_and_exchange (&rec_mutex->p, NULL, impl))
-        g_cleanup_list_push (G_CLEANUP_LIST, (GCleanupFunc)g_rec_mutex_impl_free, impl,
+        g_cleanup_list_push (G_CLEANUP_LOCAL, (GCleanupFunc)g_rec_mutex_impl_free, impl,
                              G_CLEANUP_PHASE_GRAVEYARD, G_STRFUNC);
       else
         g_rec_mutex_impl_free (impl);
@@ -466,7 +466,7 @@ g_rw_lock_get_impl (GRWLock *lock)
     {
       impl = g_rw_lock_impl_new ();
       if (g_atomic_pointer_compare_and_exchange (&lock->p, NULL, impl))
-        g_cleanup_list_push (G_CLEANUP_LIST, (GCleanupFunc)g_rw_lock_impl_free, impl,
+        g_cleanup_list_push (G_CLEANUP_LOCAL, (GCleanupFunc)g_rw_lock_impl_free, impl,
                              G_CLEANUP_PHASE_GRAVEYARD, G_STRFUNC);
       else
         g_rw_lock_impl_free (impl);
@@ -686,7 +686,7 @@ g_cond_get_impl (GCond *cond)
     {
       impl = g_cond_impl_new ();
       if (g_atomic_pointer_compare_and_exchange (&cond->p, NULL, impl))
-        g_cleanup_list_push (G_CLEANUP_LIST, (GCleanupFunc)g_cond_impl_free, impl,
+        g_cleanup_list_push (G_CLEANUP_LOCAL, (GCleanupFunc)g_cond_impl_free, impl,
                              G_CLEANUP_PHASE_GRAVEYARD, G_STRFUNC);
       else
         g_cond_impl_free (impl);
@@ -1024,9 +1024,9 @@ g_private_get_impl (GPrivate *key)
       if (g_atomic_pointer_compare_and_exchange (&key->p, NULL, impl))
         {
           g_cleanup_list_push (key->cleanup, (GCleanupFunc)g_private_cleanup, key,
-                               G_CLEANUP_PHASE_LATE, G_STRFUNC);
+                               G_CLEANUP_PHASE_LATE, "g_private_cleaunp");
           g_cleanup_list_push (key->cleanup, (GCleanupFunc)g_private_impl_free, impl,
-                               G_CLEANUP_PHASE_GRAVEYARD, G_STRFUNC);
+                               G_CLEANUP_PHASE_GRAVEYARD, "g_private_impl_free");
         }
       else
         {
diff --git a/glib/gthread.h b/glib/gthread.h
index daed459..53548d3 100644
--- a/glib/gthread.h
+++ b/glib/gthread.h
@@ -85,7 +85,7 @@ struct _GRecMutex
   guint i[2];
 };
 
-#define G_PRIVATE_INIT(notify) { NULL, (notify), G_CLEANUP_LIST, { NULL } }
+#define G_PRIVATE_INIT(notify) { NULL, (notify), G_CLEANUP_LOCAL, { NULL } }
 struct _GPrivate
 {
   /*< private >*/
diff --git a/gobject/gbinding.c b/gobject/gbinding.c
index 00e766e..4a7ccea 100644
--- a/gobject/gbinding.c
+++ b/gobject/gbinding.c
@@ -135,7 +135,7 @@ g_binding_flags_get_type (void)
       };
       GType g_define_type_id =
         g_flags_register_static (g_intern_static_string ("GBindingFlags"), values);
-      g_type_cleanup_push (G_CLEANUP_LIST, g_define_type_id);
+      g_type_cleanup_push (G_CLEANUP_LOCAL, g_define_type_id);
       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
     }
 
diff --git a/gobject/gboxed.c b/gobject/gboxed.c
index 3e00afb..e31a71e 100644
--- a/gobject/gboxed.c
+++ b/gobject/gboxed.c
@@ -108,7 +108,7 @@ _g_boxed_type_init (void)
    */
   type = g_type_register_fundamental (G_TYPE_BOXED, g_intern_static_string ("GBoxed"), &info, &finfo,
                                      G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT);
-  g_type_cleanup_push (G_CLEANUP_LIST, type);
+  g_type_cleanup_push (G_CLEANUP_LOCAL, type);
   g_assert (type == G_TYPE_BOXED);
 }
 
@@ -178,7 +178,7 @@ g_strv_get_type (void)
         g_boxed_type_register_static (g_intern_static_string ("GStrv"),
                                       (GBoxedCopyFunc) g_strdupv,
                                       (GBoxedFreeFunc) g_strfreev);
-      g_type_cleanup_push (G_CLEANUP_LIST, g_define_type_id);
+      g_type_cleanup_push (G_CLEANUP_LOCAL, g_define_type_id);
       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
     }
 
diff --git a/gobject/genums.c b/gobject/genums.c
index 1a8de8f..a3e2814 100644
--- a/gobject/genums.c
+++ b/gobject/genums.c
@@ -113,7 +113,7 @@ _g_enum_types_init (void)
   info.class_size = sizeof (GEnumClass);
   type = g_type_register_fundamental (G_TYPE_ENUM, g_intern_static_string ("GEnum"), &info, &finfo,
                                      G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT);
-  g_type_cleanup_push (G_CLEANUP_LIST, type);
+  g_type_cleanup_push (G_CLEANUP_LOCAL, type);
   g_assert (type == G_TYPE_ENUM);
   
   /* G_TYPE_FLAGS
@@ -121,7 +121,7 @@ _g_enum_types_init (void)
   info.class_size = sizeof (GFlagsClass);
   type = g_type_register_fundamental (G_TYPE_FLAGS, g_intern_static_string ("GFlags"), &info, &finfo,
                                      G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT);
-  g_type_cleanup_push (G_CLEANUP_LIST, type);
+  g_type_cleanup_push (G_CLEANUP_LOCAL, type);
   g_assert (type == G_TYPE_FLAGS);
 }
 
diff --git a/gobject/gobject.c b/gobject/gobject.c
index b3cd8b1..fb03838 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -393,7 +393,7 @@ _g_object_type_init (void)
    */
   info.value_table = &value_table;
   type = g_type_register_fundamental (G_TYPE_OBJECT, g_intern_static_string ("GObject"), &info, &finfo, 0);
-  g_type_cleanup_push (G_CLEANUP_LIST, type);
+  g_type_cleanup_push (G_CLEANUP_LOCAL, type);
   g_assert (type == G_TYPE_OBJECT);
   g_value_register_transform_func (G_TYPE_OBJECT, G_TYPE_OBJECT, g_value_object_transform_value);
   
@@ -401,7 +401,7 @@ _g_object_type_init (void)
   IF_DEBUG (OBJECTS)
     {
       debug_objects_ht = g_hash_table_new (g_direct_hash, NULL);
-      g_cleanup_list_push (G_CLEANUP_LIST, (GCleanupFunc)g_hash_table_unref, debug_objects_ht,
+      g_cleanup_list_push (G_CLEANUP_LOCAL, (GCleanupFunc)g_hash_table_unref, debug_objects_ht,
                            G_CLEANUP_PHASE_GRAVEYARD, "debug_objects_ht");
 #ifndef G_HAS_CONSTRUCTORS
       g_atexit (debug_objects_atexit);
diff --git a/gobject/gparam.c b/gobject/gparam.c
index fd7c7ec..a8a1500 100644
--- a/gobject/gparam.c
+++ b/gobject/gparam.c
@@ -137,7 +137,7 @@ _g_param_type_init (void)
    */
   type = g_type_register_fundamental (G_TYPE_PARAM, g_intern_static_string ("GParam"), &param_spec_info, 
&finfo, G_TYPE_FLAG_ABSTRACT);
   g_assert (type == G_TYPE_PARAM);
-  g_type_cleanup_push (G_CLEANUP_LIST, type);
+  g_type_cleanup_push (G_CLEANUP_LOCAL, type);
   g_param_private_offset = g_type_add_instance_private (type, sizeof (GParamSpecPrivate));
   g_value_register_transform_func (G_TYPE_PARAM, G_TYPE_PARAM, value_param_transform_value);
 }
@@ -1433,7 +1433,7 @@ g_param_type_register_static (const gchar              *name,
   cinfo->value_validate = pspec_info->value_validate;
   cinfo->values_cmp = pspec_info->values_cmp ? pspec_info->values_cmp : default_values_cmp;
   info.class_data = cinfo;
-  g_cleanup_list_push (G_CLEANUP_LIST, g_free, cinfo, G_CLEANUP_PHASE_GRAVEYARD, "cinfo");
+  g_cleanup_list_push (G_CLEANUP_LOCAL, g_free, cinfo, G_CLEANUP_PHASE_GRAVEYARD, "cinfo");
 
   return g_type_register_static (G_TYPE_PARAM, name, &info, 0);
 }
diff --git a/gobject/gparamspecs.c b/gobject/gparamspecs.c
index 12d21d5..c50af69 100644
--- a/gobject/gparamspecs.c
+++ b/gobject/gparamspecs.c
@@ -1593,7 +1593,7 @@ _g_param_spec_types_init (void)
   g_assert (spec_types == spec_types_bound);
 
   for (i = 0; i < G_N_ELEMENTS (types); i++)
-    g_type_cleanup_push (G_CLEANUP_LIST, g_param_spec_types[i]);
+    g_type_cleanup_push (G_CLEANUP_LOCAL, g_param_spec_types[i]);
 }
 
 /* --- GParamSpec initialization --- */
diff --git a/gobject/gsignal.c b/gobject/gsignal.c
index cf9a230..7be70a7 100644
--- a/gobject/gsignal.c
+++ b/gobject/gsignal.c
@@ -855,7 +855,7 @@ _g_signal_init (void)
       g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes);
       g_signal_nodes[0] = NULL;
 
-      g_cleanup_list_push (G_CLEANUP_LIST, (GCleanupFunc)signal_cleanup, NULL,
+      g_cleanup_list_push (G_CLEANUP_LOCAL, (GCleanupFunc)signal_cleanup, NULL,
                            G_CLEANUP_PHASE_GRAVEYARD, "signal_cleanup");
     }
   SIGNAL_UNLOCK ();
diff --git a/gobject/gsourceclosure.c b/gobject/gsourceclosure.c
index 196a232..f86465a 100644
--- a/gobject/gsourceclosure.c
+++ b/gobject/gsourceclosure.c
@@ -47,7 +47,7 @@ g_io_condition_get_type (void)
        { 0, NULL, NULL }
       };
       etype = g_flags_register_static ("GIOCondition", values);
-      g_type_cleanup_push (G_CLEANUP_LIST, etype);
+      g_type_cleanup_push (G_CLEANUP_LOCAL, etype);
     }
   return etype;
 }
diff --git a/gobject/gtype.c b/gobject/gtype.c
index 8f44c7d..715ab1a 100644
--- a/gobject/gtype.c
+++ b/gobject/gtype.c
@@ -4380,7 +4380,7 @@ gobject_init_ctor (void)
    */
   node = type_node_fundamental_new_W (G_TYPE_NONE, g_intern_static_string ("void"), 0);
   type = NODE_TYPE (node);
-  g_type_cleanup_push (G_CLEANUP_LIST, type);
+  g_type_cleanup_push (G_CLEANUP_LOCAL, type);
   g_assert (type == G_TYPE_NONE);
   
   /* interface fundamental type G_TYPE_INTERFACE (!classed)
@@ -4389,7 +4389,7 @@ gobject_init_ctor (void)
   node = type_node_fundamental_new_W (G_TYPE_INTERFACE, g_intern_static_string ("GInterface"), 
G_TYPE_FLAG_DERIVABLE);
   type = NODE_TYPE (node);
   type_data_make_W (node, &info, NULL);
-  g_type_cleanup_push (G_CLEANUP_LIST, type);
+  g_type_cleanup_push (G_CLEANUP_LOCAL, type);
   g_assert (type == G_TYPE_INTERFACE);
   
   G_WRITE_UNLOCK (&type_rw_lock);
@@ -4432,7 +4432,7 @@ gobject_init_ctor (void)
    */
   _g_signal_init ();
 
-  g_cleanup_list_push (G_CLEANUP_LIST, (GCleanupFunc)type_cleanup, NULL,
+  g_cleanup_list_push (G_CLEANUP_LOCAL, (GCleanupFunc)type_cleanup, NULL,
                        G_CLEANUP_PHASE_GRAVEYARD, "type_cleanup");
 }
 
@@ -5051,20 +5051,22 @@ type_cleanup (void)
   g_hash_table_unref (vtables);
   g_hash_table_unref (static_type_nodes_ht);
   static_type_nodes_ht = NULL;
+
+  _g_atomic_array_cleanup ();
 }
 
 void
 g_type_cleanup_push (GCleanupList *cleanup,
                      GType type)
 {
-  GCleanupPhase phase;
+  gint phase;
 
   /*
    * For types in our own module, we want them finalized before
    * the above infrastructure.
    */
-  if (cleanup == G_CLEANUP_LIST)
-    phase = G_CLEANUP_PHASE_MAIN;
+  if (cleanup == G_CLEANUP_LOCAL)
+    phase = G_CLEANUP_PHASE_DEFAULT;
   else
     phase = G_CLEANUP_PHASE_LATE;
 
diff --git a/gobject/gtype.h b/gobject/gtype.h
index cab0a96..b5c5cd8 100644
--- a/gobject/gtype.h
+++ b/gobject/gtype.h
@@ -1454,7 +1454,7 @@ guint     g_type_get_type_registration_serial (void);
  *                                        sizeof (GtkGadget),
  *                                        (GInstanceInitFunc) gtk_gadget_init,
  *                                        0);
- *       g_type_cleanup_push (G_CLEANUP_LIST, g_define_type_id); \
+ *       g_type_cleanup_push (G_CLEANUP_LOCAL, g_define_type_id); \
  *       {
  *         const GInterfaceInfo g_implement_interface_info = {
  *           (GInterfaceInitFunc) gtk_gadget_gizmo_init
@@ -1702,7 +1702,7 @@ type_name##_get_type (void) \
                                        sizeof (TypeName), \
                                        (GInstanceInitFunc) type_name##_init, \
                                        (GTypeFlags) flags); \
-      g_type_cleanup_push (G_CLEANUP_LIST, g_define_type_id); \
+      g_type_cleanup_push (G_CLEANUP_LOCAL, g_define_type_id); \
       { /* custom code follows */
 #define _G_DEFINE_TYPE_EXTENDED_END()  \
         /* following custom code */    \
@@ -1730,7 +1730,7 @@ type_name##_get_type (void) \
                                        0, \
                                        (GInstanceInitFunc)NULL, \
                                        (GTypeFlags) 0); \
-      g_type_cleanup_push (G_CLEANUP_LIST, g_define_type_id); \
+      g_type_cleanup_push (G_CLEANUP_LOCAL, g_define_type_id); \
       if (TYPE_PREREQ) \
         g_type_interface_add_prerequisite (g_define_type_id, TYPE_PREREQ); \
       { /* custom code follows */
@@ -1801,7 +1801,7 @@ type_name##_get_type (void) \
         ) = g_boxed_type_register_static; \
       GType g_define_type_id = \
         _g_register_boxed (g_intern_static_string (#TypeName), copy_func, free_func); \
-      g_type_cleanup_push (G_CLEANUP_LIST, g_define_type_id); \
+      g_type_cleanup_push (G_CLEANUP_LOCAL, g_define_type_id); \
       { /* custom code follows */
 #else
 #define _G_DEFINE_BOXED_TYPE_BEGIN(TypeName, type_name, copy_func, free_func) \
@@ -1815,7 +1815,7 @@ type_name##_get_type (void) \
         g_boxed_type_register_static (g_intern_static_string (#TypeName), \
                                       (GBoxedCopyFunc) copy_func, \
                                       (GBoxedFreeFunc) free_func); \
-      g_type_cleanup_push (G_CLEANUP_LIST, g_define_type_id); \
+      g_type_cleanup_push (G_CLEANUP_LOCAL, g_define_type_id); \
       { /* custom code follows */
 #endif /* __GNUC__ */
 
@@ -1855,7 +1855,7 @@ type_name##_get_type (void) \
     { \
       GType g_define_type_id = \
         g_pointer_type_register_static (g_intern_static_string (#TypeName)); \
-      g_type_cleanup_push (G_CLEANUP_LIST, g_define_type_id); \
+      g_type_cleanup_push (G_CLEANUP_LOCAL, g_define_type_id); \
       { /* custom code follows */
 
 /* --- protected (for fundamental type implementations) --- */
diff --git a/gobject/gtypemodule.c b/gobject/gtypemodule.c
index 4718a1a..8101afa 100644
--- a/gobject/gtypemodule.c
+++ b/gobject/gtypemodule.c
@@ -172,7 +172,7 @@ g_type_module_get_type (void)
 
       type_module_type = g_type_register_static (G_TYPE_OBJECT, g_intern_static_string ("GTypeModule"), 
&type_module_info, G_TYPE_FLAG_ABSTRACT);
       g_type_add_interface_static (type_module_type, G_TYPE_TYPE_PLUGIN, &iface_info);
-      g_type_cleanup_push (G_CLEANUP_LIST, type_module_type);
+      g_type_cleanup_push (G_CLEANUP_LOCAL, type_module_type);
     }
   
   return type_module_type;
diff --git a/gobject/gtypemodule.h b/gobject/gtypemodule.h
index 2af7df2..451700f 100644
--- a/gobject/gtypemodule.h
+++ b/gobject/gtypemodule.h
@@ -219,7 +219,7 @@ type_name##_register_type (GTypeModule *type_module) \
                                                     (GTypeFlags) flags); \
   g_define_type_id = type_name##_type_id; \
   if (!previous) \
-    g_type_cleanup_push (G_CLEANUP_LIST, g_define_type_id); \
+    g_type_cleanup_push (G_CLEANUP_LOCAL, g_define_type_id); \
   { CODE ; } \
 }
 
diff --git a/gobject/gtypeplugin.c b/gobject/gtypeplugin.c
index 6b5ce91..bc49f9b 100644
--- a/gobject/gtypeplugin.c
+++ b/gobject/gtypeplugin.c
@@ -102,7 +102,7 @@ g_type_plugin_get_type (void)
       };
       
       type_plugin_type = g_type_register_static (G_TYPE_INTERFACE, g_intern_static_string ("GTypePlugin"), 
&type_plugin_info, 0);
-      g_type_cleanup_push (G_CLEANUP_LIST, type_plugin_type);
+      g_type_cleanup_push (G_CLEANUP_LOCAL, type_plugin_type);
     }
   
   return type_plugin_type;
diff --git a/gobject/gvaluetypes.c b/gobject/gvaluetypes.c
index c4018d7..a802e0e 100644
--- a/gobject/gvaluetypes.c
+++ b/gobject/gvaluetypes.c
@@ -455,10 +455,10 @@ _g_value_types_init (void)
     info.value_table = &value_table;
     type = g_type_register_fundamental (G_TYPE_CHAR, g_intern_static_string ("gchar"), &info, &finfo, 0);
     g_assert (type == G_TYPE_CHAR);
-    g_type_cleanup_push (G_CLEANUP_LIST, type);
+    g_type_cleanup_push (G_CLEANUP_LOCAL, type);
     type = g_type_register_fundamental (G_TYPE_UCHAR, g_intern_static_string ("guchar"), &info, &finfo, 0);
     g_assert (type == G_TYPE_UCHAR);
-    g_type_cleanup_push (G_CLEANUP_LIST, type);
+    g_type_cleanup_push (G_CLEANUP_LOCAL, type);
   }
 
   /* G_TYPE_BOOLEAN
@@ -477,7 +477,7 @@ _g_value_types_init (void)
     info.value_table = &value_table;
     type = g_type_register_fundamental (G_TYPE_BOOLEAN, g_intern_static_string ("gboolean"), &info, &finfo, 
0);
     g_assert (type == G_TYPE_BOOLEAN);
-    g_type_cleanup_push (G_CLEANUP_LIST, type);
+    g_type_cleanup_push (G_CLEANUP_LOCAL, type);
   }
   
   /* G_TYPE_INT / G_TYPE_UINT
@@ -496,10 +496,10 @@ _g_value_types_init (void)
     info.value_table = &value_table;
     type = g_type_register_fundamental (G_TYPE_INT, g_intern_static_string ("gint"), &info, &finfo, 0);
     g_assert (type == G_TYPE_INT);
-    g_type_cleanup_push (G_CLEANUP_LIST, type);
+    g_type_cleanup_push (G_CLEANUP_LOCAL, type);
     type = g_type_register_fundamental (G_TYPE_UINT, g_intern_static_string ("guint"), &info, &finfo, 0);
     g_assert (type == G_TYPE_UINT);
-    g_type_cleanup_push (G_CLEANUP_LIST, type);
+    g_type_cleanup_push (G_CLEANUP_LOCAL, type);
   }
 
   /* G_TYPE_LONG / G_TYPE_ULONG
@@ -518,10 +518,10 @@ _g_value_types_init (void)
     info.value_table = &value_table;
     type = g_type_register_fundamental (G_TYPE_LONG, g_intern_static_string ("glong"), &info, &finfo, 0);
     g_assert (type == G_TYPE_LONG);
-    g_type_cleanup_push (G_CLEANUP_LIST, type);
+    g_type_cleanup_push (G_CLEANUP_LOCAL, type);
     type = g_type_register_fundamental (G_TYPE_ULONG, g_intern_static_string ("gulong"), &info, &finfo, 0);
     g_assert (type == G_TYPE_ULONG);
-    g_type_cleanup_push (G_CLEANUP_LIST, type);
+    g_type_cleanup_push (G_CLEANUP_LOCAL, type);
   }
   
   /* G_TYPE_INT64 / G_TYPE_UINT64
@@ -540,10 +540,10 @@ _g_value_types_init (void)
     info.value_table = &value_table;
     type = g_type_register_fundamental (G_TYPE_INT64, g_intern_static_string ("gint64"), &info, &finfo, 0);
     g_assert (type == G_TYPE_INT64);
-    g_type_cleanup_push (G_CLEANUP_LIST, type);
+    g_type_cleanup_push (G_CLEANUP_LOCAL, type);
     type = g_type_register_fundamental (G_TYPE_UINT64, g_intern_static_string ("guint64"), &info, &finfo, 0);
     g_assert (type == G_TYPE_UINT64);
-    g_type_cleanup_push (G_CLEANUP_LIST, type);
+    g_type_cleanup_push (G_CLEANUP_LOCAL, type);
   }
   
   /* G_TYPE_FLOAT
@@ -562,7 +562,7 @@ _g_value_types_init (void)
     info.value_table = &value_table;
     type = g_type_register_fundamental (G_TYPE_FLOAT, g_intern_static_string ("gfloat"), &info, &finfo, 0);
     g_assert (type == G_TYPE_FLOAT);
-    g_type_cleanup_push (G_CLEANUP_LIST, type);
+    g_type_cleanup_push (G_CLEANUP_LOCAL, type);
   }
   
   /* G_TYPE_DOUBLE
@@ -581,7 +581,7 @@ _g_value_types_init (void)
     info.value_table = &value_table;
     type = g_type_register_fundamental (G_TYPE_DOUBLE, g_intern_static_string ("gdouble"), &info, &finfo, 0);
     g_assert (type == G_TYPE_DOUBLE);
-    g_type_cleanup_push (G_CLEANUP_LIST, type);
+    g_type_cleanup_push (G_CLEANUP_LOCAL, type);
   }
 
   /* G_TYPE_STRING
@@ -600,7 +600,7 @@ _g_value_types_init (void)
     info.value_table = &value_table;
     type = g_type_register_fundamental (G_TYPE_STRING, g_intern_static_string ("gchararray"), &info, &finfo, 
0);
     g_assert (type == G_TYPE_STRING);
-    g_type_cleanup_push (G_CLEANUP_LIST, type);
+    g_type_cleanup_push (G_CLEANUP_LOCAL, type);
   }
 
   /* G_TYPE_POINTER
@@ -619,7 +619,7 @@ _g_value_types_init (void)
     info.value_table = &value_table;
     type = g_type_register_fundamental (G_TYPE_POINTER, g_intern_static_string ("gpointer"), &info, &finfo, 
0);
     g_assert (type == G_TYPE_POINTER);
-    g_type_cleanup_push (G_CLEANUP_LIST, type);
+    g_type_cleanup_push (G_CLEANUP_LOCAL, type);
   }
 
   /* G_TYPE_VARIANT
@@ -638,7 +638,7 @@ _g_value_types_init (void)
     info.value_table = &value_table;
     type = g_type_register_fundamental (G_TYPE_VARIANT, g_intern_static_string ("GVariant"), &info, &finfo, 
0);
     g_assert (type == G_TYPE_VARIANT);
-    g_type_cleanup_push (G_CLEANUP_LIST, type);
+    g_type_cleanup_push (G_CLEANUP_LOCAL, type);
   }
 }
 
diff --git a/gobject/tests/dynamictests.c b/gobject/tests/dynamictests.c
index 4ad30fe..be51dd0 100644
--- a/gobject/tests/dynamictests.c
+++ b/gobject/tests/dynamictests.c
@@ -96,7 +96,7 @@ static GType test_module_get_type (void)
        (GInstanceInitFunc)NULL
       };
     object_type = g_type_register_static (G_TYPE_TYPE_MODULE, "TestModule", &object_info, 0);
-    g_type_cleanup_push (G_CLEANUP_LIST, object_type);
+    g_type_cleanup_push (G_CLEANUP_LOCAL, object_type);
   }
   return object_type;
 }
diff --git a/gobject/tests/enums.c b/gobject/tests/enums.c
index 3488079..7e52a95 100644
--- a/gobject/tests/enums.c
+++ b/gobject/tests/enums.c
@@ -17,7 +17,7 @@ test_enum_basic (void)
   GValue value = G_VALUE_INIT;
 
   type = g_enum_register_static ("MyEnum", my_enum_values);
-  g_type_cleanup_push (G_CLEANUP_LIST, type);
+  g_type_cleanup_push (G_CLEANUP_LOCAL, type);
 
   g_value_init (&value, type);
   g_assert (G_VALUE_HOLDS_ENUM (&value));
@@ -81,7 +81,7 @@ test_flags_basic (void)
   GValue value = G_VALUE_INIT;
 
   type = g_flags_register_static ("MyFlags", my_flag_values);
-  g_type_cleanup_push (G_CLEANUP_LIST, type);
+  g_type_cleanup_push (G_CLEANUP_LOCAL, type);
 
   g_value_init (&value, type);
   g_assert (G_VALUE_HOLDS_FLAGS (&value));
diff --git a/gobject/tests/signals.c b/gobject/tests/signals.c
index 03d16a9..198331d 100644
--- a/gobject/tests/signals.c
+++ b/gobject/tests/signals.c
@@ -32,7 +32,7 @@ test_enum_get_type (void)
       };
       GType g_define_type_id =
         g_enum_register_static (g_intern_static_string ("TestEnum"), values);
-      g_type_cleanup_push (G_CLEANUP_LIST, g_define_type_id);
+      g_type_cleanup_push (G_CLEANUP_LOCAL, g_define_type_id);
       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
     }
 
@@ -53,7 +53,7 @@ test_unsigned_enum_get_type (void)
       };
       GType g_define_type_id =
         g_enum_register_static (g_intern_static_string ("TestUnsignedEnum"), values);
-      g_type_cleanup_push (G_CLEANUP_LIST, g_define_type_id);
+      g_type_cleanup_push (G_CLEANUP_LOCAL, g_define_type_id);
       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
     }
 
@@ -111,9 +111,9 @@ test_class_init (TestClass *klass)
   guint s;
 
   enum_type = g_enum_register_static ("MyEnum", my_enum_values);
-  g_type_cleanup_push (G_CLEANUP_LIST, enum_type);
+  g_type_cleanup_push (G_CLEANUP_LOCAL, enum_type);
   flags_type = g_flags_register_static ("MyFlag", my_flag_values);
-  g_type_cleanup_push (G_CLEANUP_LIST, flags_type);
+  g_type_cleanup_push (G_CLEANUP_LOCAL, flags_type);
 
   klass->all_types = all_types_handler;
 
diff --git a/gobject/tests/testcommon.h b/gobject/tests/testcommon.h
index a793ccd..0be819a 100644
--- a/gobject/tests/testcommon.h
+++ b/gobject/tests/testcommon.h
@@ -48,7 +48,7 @@ prefix ## _get_type (void)                                    \
       object_type = g_type_register_static (parent_type,       \
                                            # name,             \
                                            &object_info, 0);   \
-      g_type_cleanup_push (G_CLEANUP_LIST, object_type);        \
+      g_type_cleanup_push (G_CLEANUP_LOCAL, object_type);       \
       interface_decl                                           \
     }                                                          \
                                                                \
@@ -80,7 +80,7 @@ prefix ## _get_type (void)                                    \
       iface_type = g_type_register_static (G_TYPE_INTERFACE,   \
                                            # name,             \
                                            &iface_info, 0);    \
-      g_type_cleanup_push (G_CLEANUP_LIST, iface_type);         \
+      g_type_cleanup_push (G_CLEANUP_LOCAL, iface_type);         \
     }                                                          \
   return iface_type;                                           \
 }
diff --git a/gobject/tests/type.c b/gobject/tests/type.c
index f307c21..fec69e5 100644
--- a/gobject/tests/type.c
+++ b/gobject/tests/type.c
@@ -8,7 +8,7 @@ test_registration_serial (void)
 
   serial1 = g_type_get_type_registration_serial ();
   type = g_pointer_type_register_static ("my+pointer");
-  g_type_cleanup_push (G_CLEANUP_LIST, type);
+  g_type_cleanup_push (G_CLEANUP_LOCAL, type);
   serial2 = g_type_get_type_registration_serial ();
   g_assert (serial1 != serial2);
   serial3 = g_type_get_type_registration_serial ();



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