mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-24 11:12:11 +01:00
Merge branch 'wip/chergert/gc-varianttypeinfo' into 'main'
gvarianttype: Garbage Collect GVariantTypeInfo Closes #3472 See merge request GNOME/glib!4275
This commit is contained in:
commit
7dfaa47832
@ -31,6 +31,7 @@
|
||||
#include <glib/ghash.h>
|
||||
#include <glib/grefcount.h>
|
||||
|
||||
#include "glib-private.h"
|
||||
#include "glib_trace.h"
|
||||
|
||||
/* < private >
|
||||
@ -740,6 +741,36 @@ g_variant_type_info_member_info (GVariantTypeInfo *info,
|
||||
/* == new/ref/unref == */
|
||||
static GRecMutex g_variant_type_info_lock;
|
||||
static GHashTable *g_variant_type_info_table;
|
||||
static GPtrArray *g_variant_type_info_gc;
|
||||
|
||||
#define GC_THRESHOLD 32
|
||||
|
||||
static void
|
||||
gc_while_locked (void)
|
||||
{
|
||||
while (g_variant_type_info_gc->len > 0)
|
||||
{
|
||||
GVariantTypeInfo *info = g_ptr_array_steal_index_fast (g_variant_type_info_gc, 0);
|
||||
ContainerInfo *container = (ContainerInfo *)info;
|
||||
|
||||
if (g_atomic_ref_count_dec (&container->ref_count))
|
||||
{
|
||||
TRACE(GLIB_VARIANT_TYPE_INFO_FREE(info));
|
||||
|
||||
g_hash_table_remove (g_variant_type_info_table,
|
||||
container->type_string);
|
||||
|
||||
g_free (container->type_string);
|
||||
|
||||
if (info->container_class == GV_ARRAY_INFO_CLASS)
|
||||
array_info_free (info);
|
||||
else if (info->container_class == GV_TUPLE_INFO_CLASS)
|
||||
tuple_info_free (info);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* < private >
|
||||
* g_variant_type_info_get:
|
||||
@ -770,8 +801,11 @@ g_variant_type_info_get (const GVariantType *type)
|
||||
g_rec_mutex_lock (&g_variant_type_info_lock);
|
||||
|
||||
if (g_variant_type_info_table == NULL)
|
||||
g_variant_type_info_table = g_hash_table_new ((GHashFunc)_g_variant_type_hash,
|
||||
(GEqualFunc)_g_variant_type_equal);
|
||||
{
|
||||
g_variant_type_info_table = g_hash_table_new ((GHashFunc)_g_variant_type_hash,
|
||||
(GEqualFunc)_g_variant_type_equal);
|
||||
g_ignore_leak (g_variant_type_info_table);
|
||||
}
|
||||
info = g_hash_table_lookup (g_variant_type_info_table, type_string);
|
||||
|
||||
if (info == NULL)
|
||||
@ -864,36 +898,36 @@ g_variant_type_info_unref (GVariantTypeInfo *info)
|
||||
g_rec_mutex_lock (&g_variant_type_info_lock);
|
||||
if (g_atomic_ref_count_dec (&container->ref_count))
|
||||
{
|
||||
|
||||
TRACE(GLIB_VARIANT_TYPE_INFO_FREE(info));
|
||||
|
||||
g_hash_table_remove (g_variant_type_info_table,
|
||||
container->type_string);
|
||||
if (g_hash_table_size (g_variant_type_info_table) == 0)
|
||||
if (g_variant_type_info_gc == NULL)
|
||||
{
|
||||
g_hash_table_unref (g_variant_type_info_table);
|
||||
g_variant_type_info_table = NULL;
|
||||
g_variant_type_info_gc = g_ptr_array_new ();
|
||||
g_ignore_leak (g_variant_type_info_gc);
|
||||
}
|
||||
g_rec_mutex_unlock (&g_variant_type_info_lock);
|
||||
|
||||
g_free (container->type_string);
|
||||
/* Steal this instance and place it onto the GC queue.
|
||||
* We may bring it back to life before the next GC.
|
||||
*/
|
||||
g_atomic_ref_count_init (&container->ref_count);
|
||||
g_ptr_array_add (g_variant_type_info_gc, info);
|
||||
|
||||
if (info->container_class == GV_ARRAY_INFO_CLASS)
|
||||
array_info_free (info);
|
||||
|
||||
else if (info->container_class == GV_TUPLE_INFO_CLASS)
|
||||
tuple_info_free (info);
|
||||
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
if (g_variant_type_info_gc->len > GC_THRESHOLD)
|
||||
gc_while_locked ();
|
||||
}
|
||||
else
|
||||
g_rec_mutex_unlock (&g_variant_type_info_lock);
|
||||
g_rec_mutex_unlock (&g_variant_type_info_lock);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
g_variant_type_info_assert_no_infos (void)
|
||||
{
|
||||
g_assert (g_variant_type_info_table == NULL);
|
||||
G_GNUC_UNUSED gboolean empty;
|
||||
|
||||
g_rec_mutex_lock (&g_variant_type_info_lock);
|
||||
if (g_variant_type_info_table != NULL)
|
||||
gc_while_locked ();
|
||||
empty = (g_variant_type_info_table == NULL ||
|
||||
g_hash_table_size (g_variant_type_info_table) == 0);
|
||||
g_rec_mutex_unlock (&g_variant_type_info_lock);
|
||||
|
||||
g_assert (empty);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user