[glib/wip/th/fix-small-array-hash-valgrind: 2/2] ghash: clear hash table before invoking cleanup functions in g_hash_table_remove_all_nodes()
- From: Thomas Haller <thaller src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/wip/th/fix-small-array-hash-valgrind: 2/2] ghash: clear hash table before invoking cleanup functions in g_hash_table_remove_all_nodes()
- Date: Wed, 15 May 2019 14:41:39 +0000 (UTC)
commit 54c8ab649dd296f6a2afdb2e2ba96541e6da36bb
Author: Thomas Haller <thaller redhat com>
Date: Wed May 15 16:36:17 2019 +0200
ghash: clear hash table before invoking cleanup functions in g_hash_table_remove_all_nodes()
Invoking the cleanup function gives control back to the caller, who
might again call into the hash-table. Probably, doing that would be
error prone and a bad idea.
Anyway, we should not call into external code while the hash table is in
an inconsistent state. Reset the have_big_keys/have_big_values flags
first.
glib/ghash.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
---
diff --git a/glib/ghash.c b/glib/ghash.c
index dbb09c373..4e980eb2c 100644
--- a/glib/ghash.c
+++ b/glib/ghash.c
@@ -581,6 +581,8 @@ g_hash_table_remove_all_nodes (GHashTable *hash_table,
gpointer *old_keys;
gpointer *old_values;
guint *old_hashes;
+ gboolean old_have_big_keys;
+ gboolean old_have_big_values;
/* If the hash table is already empty, there is nothing to be done. */
if (hash_table->nnodes == 0)
@@ -610,10 +612,12 @@ g_hash_table_remove_all_nodes (GHashTable *hash_table,
}
/* Keep the old storage space around to iterate over it. */
- old_size = hash_table->size;
- old_keys = hash_table->keys;
- old_values = hash_table->values;
- old_hashes = hash_table->hashes;
+ old_size = hash_table->size;
+ old_keys = hash_table->keys;
+ old_values = hash_table->values;
+ old_hashes = hash_table->hashes;
+ old_have_big_keys = hash_table->have_big_keys;
+ old_have_big_values = hash_table->have_big_values;
/* Now create a new storage space; If the table is destroyed we can use the
* shortcut of not creating a new storage. This saves the allocation at the
@@ -635,17 +639,20 @@ g_hash_table_remove_all_nodes (GHashTable *hash_table,
hash_table->hashes = NULL;
}
+ hash_table->have_big_keys = !hash_table->use_small_arrays;
+ hash_table->have_big_values = !hash_table->use_small_arrays;
+
for (i = 0; i < old_size; i++)
{
if (HASH_IS_REAL (old_hashes[i]))
{
- key = g_hash_table_fetch_key_or_value (old_keys, i, hash_table->have_big_keys);
- value = g_hash_table_fetch_key_or_value (old_values, i, hash_table->have_big_values);
+ key = g_hash_table_fetch_key_or_value (old_keys, i, old_have_big_keys);
+ value = g_hash_table_fetch_key_or_value (old_values, i, old_have_big_values);
old_hashes[i] = UNUSED_HASH_VALUE;
- g_hash_table_assign_key_or_value (old_keys, i, hash_table->have_big_keys, NULL);
- g_hash_table_assign_key_or_value (old_values, i, hash_table->have_big_values, NULL);
+ g_hash_table_assign_key_or_value (old_keys, i, old_have_big_keys, NULL);
+ g_hash_table_assign_key_or_value (old_values, i, old_have_big_values, NULL);
if (hash_table->key_destroy_func != NULL)
hash_table->key_destroy_func (key);
@@ -655,9 +662,6 @@ g_hash_table_remove_all_nodes (GHashTable *hash_table,
}
}
- hash_table->have_big_keys = !hash_table->use_small_arrays;
- hash_table->have_big_values = !hash_table->use_small_arrays;
-
/* Destroy old storage space. */
if (old_keys != old_values)
g_free (old_values);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]