X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbus%2Fdbus-hash.c;h=c80835aaafe0fe8d38b2fe8131899f8df8eb8650;hb=61d97215c317a4154df47fbfb882aab60b92fbab;hp=d7791d2ac880009f5534e5e49e577a94db96ead5;hpb=8925ff6d9870ccaab0feeb4f9af6e1f075d313ef;p=platform%2Fupstream%2Fdbus.git diff --git a/dbus/dbus-hash.c b/dbus/dbus-hash.c index d7791d2..c80835a 100644 --- a/dbus/dbus-hash.c +++ b/dbus/dbus-hash.c @@ -1,5 +1,5 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-hash.c Generic hash table utility (internal to D-BUS implementation) +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-hash.c Generic hash table utility (internal to D-Bus implementation) * * Copyright (C) 2002 Red Hat, Inc. * Copyright (c) 1991-1993 The Regents of the University of California. @@ -7,10 +7,10 @@ * * Hash table implementation based on generic/tclHash.c from the Tcl * source code. The original Tcl license applies to portions of the - * code from tclHash.c; the Tcl license follows this standad D-BUS + * code from tclHash.c; the Tcl license follows this standad D-Bus * license information. * - * Licensed under the Academic Free License version 1.2 + * Licensed under the Academic Free License version 2.1 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,7 +24,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* @@ -74,6 +74,7 @@ * accordance with the terms specified in this license. */ +#include #include "dbus-hash.h" #include "dbus-internals.h" #include "dbus-mempool.h" @@ -119,7 +120,7 @@ * */ #define RANDOM_INDEX(table, i) \ - (((((long) (i))*1103515245) >> (table)->down_shift) & (table)->mask) + (((((intptr_t) (i))*1103515245) >> (table)->down_shift) & (table)->mask) /** * Initial number of buckets in hash table (hash table statically @@ -152,10 +153,11 @@ struct DBusHashEntry /** * Function used to find and optionally create a hash entry. */ -typedef DBusHashEntry* (* DBusFindEntryFunction) (DBusHashTable *table, - void *key, - dbus_bool_t create_if_not_found, - DBusHashEntry ***bucket); +typedef DBusHashEntry* (* DBusFindEntryFunction) (DBusHashTable *table, + void *key, + dbus_bool_t create_if_not_found, + DBusHashEntry ***bucket, + DBusPreallocatedHash *preallocated); /** * @brief Internals of DBusHashTable. @@ -220,24 +222,29 @@ typedef struct int n_entries_on_init; /**< used to detect table resize since initialization */ } DBusRealHashIter; -static DBusHashEntry* find_direct_function (DBusHashTable *table, - void *key, - dbus_bool_t create_if_not_found, - DBusHashEntry ***bucket); -static DBusHashEntry* find_string_function (DBusHashTable *table, - void *key, - dbus_bool_t create_if_not_found, - DBusHashEntry ***bucket); -static unsigned int string_hash (const char *str); -static void rebuild_table (DBusHashTable *table); -static DBusHashEntry* alloc_entry (DBusHashTable *table); -static void remove_entry (DBusHashTable *table, - DBusHashEntry **bucket, - DBusHashEntry *entry); -static void free_entry (DBusHashTable *table, - DBusHashEntry *entry); -static void free_entry_data (DBusHashTable *table, - DBusHashEntry *entry); +_DBUS_STATIC_ASSERT (sizeof (DBusRealHashIter) == sizeof (DBusHashIter)); + +static DBusHashEntry* find_direct_function (DBusHashTable *table, + void *key, + dbus_bool_t create_if_not_found, + DBusHashEntry ***bucket, + DBusPreallocatedHash *preallocated); +static DBusHashEntry* find_string_function (DBusHashTable *table, + void *key, + dbus_bool_t create_if_not_found, + DBusHashEntry ***bucket, + DBusPreallocatedHash *preallocated); +static unsigned int string_hash (const char *str); +static void rebuild_table (DBusHashTable *table); +static DBusHashEntry* alloc_entry (DBusHashTable *table); +static void remove_entry (DBusHashTable *table, + DBusHashEntry **bucket, + DBusHashEntry *entry); +static void free_entry (DBusHashTable *table, + DBusHashEntry *entry); +static void free_entry_data (DBusHashTable *table, + DBusHashEntry *entry); + /** @} */ @@ -312,7 +319,7 @@ _dbus_hash_table_new (DBusHashType type, switch (table->key_type) { case DBUS_HASH_INT: - case DBUS_HASH_POINTER: + case DBUS_HASH_UINTPTR: table->find_function = find_direct_function; break; case DBUS_HASH_STRING: @@ -334,11 +341,14 @@ _dbus_hash_table_new (DBusHashType type, * Increments the reference count for a hash table. * * @param table the hash table to add a reference to. + * @returns the hash table. */ -void +DBusHashTable * _dbus_hash_table_ref (DBusHashTable *table) { table->refcount += 1; + + return table; } /** @@ -399,6 +409,22 @@ _dbus_hash_table_unref (DBusHashTable *table) } } +/** + * Removed all entries from a hash table. + * + * @param table the hash table to remove all entries from. + */ +void +_dbus_hash_table_remove_all (DBusHashTable *table) +{ + DBusHashIter iter; + _dbus_hash_iter_init (table, &iter); + while (_dbus_hash_iter_next (&iter)) + { + _dbus_hash_iter_remove_entry(&iter); + } +} + static DBusHashEntry* alloc_entry (DBusHashTable *table) { @@ -644,6 +670,25 @@ _dbus_hash_iter_get_int_key (DBusHashIter *iter) /** * Gets the key for the current entry. + * Only works for hash tables of type #DBUS_HASH_UINTPTR. + * + * @param iter the hash table iterator. + */ +uintptr_t +_dbus_hash_iter_get_uintptr_key (DBusHashIter *iter) +{ + DBusRealHashIter *real; + + real = (DBusRealHashIter*) iter; + + _dbus_assert (real->table != NULL); + _dbus_assert (real->entry != NULL); + + return (uintptr_t) real->entry->key; +} + +/** + * Gets the key for the current entry. * Only works for hash tables of type #DBUS_HASH_STRING * @param iter the hash table iterator. */ @@ -705,7 +750,7 @@ _dbus_hash_iter_lookup (DBusHashTable *table, real = (DBusRealHashIter*) iter; - entry = (* table->find_function) (table, key, create_if_not_found, &bucket); + entry = (* table->find_function) (table, key, create_if_not_found, &bucket, NULL); if (entry == NULL) return FALSE; @@ -722,22 +767,14 @@ _dbus_hash_iter_lookup (DBusHashTable *table, return TRUE; } -static DBusHashEntry* -add_entry (DBusHashTable *table, - unsigned int idx, - void *key, - DBusHashEntry ***bucket) +static void +add_allocated_entry (DBusHashTable *table, + DBusHashEntry *entry, + unsigned int idx, + void *key, + DBusHashEntry ***bucket) { - DBusHashEntry *entry; - DBusHashEntry **b; - - entry = alloc_entry (table); - if (entry == NULL) - { - if (bucket) - *bucket = NULL; - return NULL; - } + DBusHashEntry **b; entry->key = key; @@ -756,68 +793,83 @@ add_entry (DBusHashTable *table, if (table->n_entries >= table->hi_rebuild_size || table->n_entries < table->lo_rebuild_size) rebuild_table (table); +} + +static DBusHashEntry* +add_entry (DBusHashTable *table, + unsigned int idx, + void *key, + DBusHashEntry ***bucket, + DBusPreallocatedHash *preallocated) +{ + DBusHashEntry *entry; + + if (preallocated == NULL) + { + entry = alloc_entry (table); + if (entry == NULL) + { + if (bucket) + *bucket = NULL; + return NULL; + } + } + else + { + entry = (DBusHashEntry*) preallocated; + } + + add_allocated_entry (table, entry, idx, key, bucket); return entry; } - + +/* This is g_str_hash from GLib which was + * extensively discussed/tested/profiled + */ static unsigned int string_hash (const char *str) { - register unsigned int result; - register int c; + const char *p = str; + unsigned int h = *p; - /* - * I tried a zillion different hash functions and asked many other - * people for advice. Many people had their own favorite functions, - * all different, but no-one had much idea why they were good ones. - * I chose the one below (multiply by 9 and add new character) - * because of the following reasons: - * - * 1. Multiplying by 10 is perfect for keys that are decimal strings, - * and multiplying by 9 is just about as good. - * 2. Times-9 is (shift-left-3) plus (old). This means that each - * character's bits hang around in the low-order bits of the - * hash value for ever, plus they spread fairly rapidly up to - * the high-order bits to fill out the hash value. This seems - * works well both for decimal and non-decimal strings. - */ + if (h) + for (p += 1; *p != '\0'; p++) + h = (h << 5) - h + *p; - result = 0; - while (TRUE) - { - c = *str; - str++; - if (c == 0) - break; - - result += (result << 3) + c; - } - - return result; + return h; } +/** Key comparison function */ +typedef int (* KeyCompareFunc) (const void *key_a, const void *key_b); + static DBusHashEntry* -find_string_function (DBusHashTable *table, - void *key, - dbus_bool_t create_if_not_found, - DBusHashEntry ***bucket) +find_generic_function (DBusHashTable *table, + void *key, + unsigned int idx, + KeyCompareFunc compare_func, + dbus_bool_t create_if_not_found, + DBusHashEntry ***bucket, + DBusPreallocatedHash *preallocated) { DBusHashEntry *entry; - unsigned int idx; if (bucket) *bucket = NULL; - - idx = string_hash (key) & table->mask; /* Search all of the entries in this bucket. */ entry = table->buckets[idx]; while (entry != NULL) { - if (strcmp (key, entry->key) == 0) + if ((compare_func == NULL && key == entry->key) || + (compare_func != NULL && (* compare_func) (key, entry->key) == 0)) { if (bucket) *bucket = &(table->buckets[idx]); + + if (preallocated) + _dbus_hash_table_free_preallocated_entry (table, preallocated); + return entry; } @@ -825,44 +877,44 @@ find_string_function (DBusHashTable *table, } if (create_if_not_found) - entry = add_entry (table, idx, key, bucket); - + entry = add_entry (table, idx, key, bucket, preallocated); + else if (preallocated) + _dbus_hash_table_free_preallocated_entry (table, preallocated); + return entry; } static DBusHashEntry* -find_direct_function (DBusHashTable *table, - void *key, - dbus_bool_t create_if_not_found, - DBusHashEntry ***bucket) +find_string_function (DBusHashTable *table, + void *key, + dbus_bool_t create_if_not_found, + DBusHashEntry ***bucket, + DBusPreallocatedHash *preallocated) { - DBusHashEntry *entry; unsigned int idx; + + idx = string_hash (key) & table->mask; - if (bucket) - *bucket = NULL; + return find_generic_function (table, key, idx, + (KeyCompareFunc) strcmp, create_if_not_found, bucket, + preallocated); +} + +static DBusHashEntry* +find_direct_function (DBusHashTable *table, + void *key, + dbus_bool_t create_if_not_found, + DBusHashEntry ***bucket, + DBusPreallocatedHash *preallocated) +{ + unsigned int idx; idx = RANDOM_INDEX (table, key) & table->mask; - /* Search all of the entries in this bucket. */ - entry = table->buckets[idx]; - while (entry != NULL) - { - if (key == entry->key) - { - if (bucket) - *bucket = &(table->buckets[idx]); - return entry; - } - - entry = entry->next; - } - - /* Entry not found. Add a new one to the bucket. */ - if (create_if_not_found) - entry = add_entry (table, idx, key, bucket); - return entry; + return find_generic_function (table, key, idx, + NULL, create_if_not_found, bucket, + preallocated); } static void @@ -963,7 +1015,7 @@ rebuild_table (DBusHashTable *table) idx = string_hash (entry->key) & table->mask; break; case DBUS_HASH_INT: - case DBUS_HASH_POINTER: + case DBUS_HASH_UINTPTR: idx = RANDOM_INDEX (table, entry->key); break; default: @@ -1001,7 +1053,7 @@ _dbus_hash_table_lookup_string (DBusHashTable *table, _dbus_assert (table->key_type == DBUS_HASH_STRING); - entry = (* table->find_function) (table, (char*) key, FALSE, NULL); + entry = (* table->find_function) (table, (char*) key, FALSE, NULL, NULL); if (entry) return entry->value; @@ -1026,7 +1078,7 @@ _dbus_hash_table_lookup_int (DBusHashTable *table, _dbus_assert (table->key_type == DBUS_HASH_INT); - entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), FALSE, NULL); + entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), FALSE, NULL, NULL); if (entry) return entry->value; @@ -1036,7 +1088,7 @@ _dbus_hash_table_lookup_int (DBusHashTable *table, /** * Looks up the value for a given integer in a hash table - * of type #DBUS_HASH_POINTER. Returns %NULL if the value + * of type #DBUS_HASH_UINTPTR. Returns %NULL if the value * is not present. (A not-present entry is indistinguishable * from an entry with a value of %NULL.) * @param table the hash table. @@ -1044,14 +1096,14 @@ _dbus_hash_table_lookup_int (DBusHashTable *table, * @returns the value of the hash entry. */ void* -_dbus_hash_table_lookup_pointer (DBusHashTable *table, - void *key) +_dbus_hash_table_lookup_uintptr (DBusHashTable *table, + uintptr_t key) { DBusHashEntry *entry; - _dbus_assert (table->key_type == DBUS_HASH_POINTER); + _dbus_assert (table->key_type == DBUS_HASH_UINTPTR); - entry = (* table->find_function) (table, key, FALSE, NULL); + entry = (* table->find_function) (table, (void*) key, FALSE, NULL, NULL); if (entry) return entry->value; @@ -1076,7 +1128,7 @@ _dbus_hash_table_remove_string (DBusHashTable *table, _dbus_assert (table->key_type == DBUS_HASH_STRING); - entry = (* table->find_function) (table, (char*) key, FALSE, &bucket); + entry = (* table->find_function) (table, (char*) key, FALSE, &bucket, NULL); if (entry) { @@ -1104,7 +1156,7 @@ _dbus_hash_table_remove_int (DBusHashTable *table, _dbus_assert (table->key_type == DBUS_HASH_INT); - entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), FALSE, &bucket); + entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), FALSE, &bucket, NULL); if (entry) { @@ -1124,15 +1176,15 @@ _dbus_hash_table_remove_int (DBusHashTable *table, * @returns #TRUE if the entry existed */ dbus_bool_t -_dbus_hash_table_remove_pointer (DBusHashTable *table, - void *key) +_dbus_hash_table_remove_uintptr (DBusHashTable *table, + uintptr_t key) { DBusHashEntry *entry; DBusHashEntry **bucket; - _dbus_assert (table->key_type == DBUS_HASH_POINTER); + _dbus_assert (table->key_type == DBUS_HASH_UINTPTR); - entry = (* table->find_function) (table, key, FALSE, &bucket); + entry = (* table->find_function) (table, (void*) key, FALSE, &bucket, NULL); if (entry) { @@ -1143,7 +1195,6 @@ _dbus_hash_table_remove_pointer (DBusHashTable *table, return FALSE; } - /** * Creates a hash entry with the given key and value. * The key and value are not copied; they are stored @@ -1164,24 +1215,17 @@ _dbus_hash_table_insert_string (DBusHashTable *table, char *key, void *value) { - DBusHashEntry *entry; + DBusPreallocatedHash *preallocated; _dbus_assert (table->key_type == DBUS_HASH_STRING); - - entry = (* table->find_function) (table, key, TRUE, NULL); - - if (entry == NULL) - return FALSE; /* no memory */ - - if (table->free_key_function && entry->key != key) - (* table->free_key_function) (entry->key); - if (table->free_value_function && entry->value != value) - (* table->free_value_function) (entry->value); - - entry->key = key; - entry->value = value; + preallocated = _dbus_hash_table_preallocate_entry (table); + if (preallocated == NULL) + return FALSE; + _dbus_hash_table_insert_string_preallocated (table, preallocated, + key, value); + return TRUE; } @@ -1209,7 +1253,7 @@ _dbus_hash_table_insert_int (DBusHashTable *table, _dbus_assert (table->key_type == DBUS_HASH_INT); - entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), TRUE, NULL); + entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), TRUE, NULL, NULL); if (entry == NULL) return FALSE; /* no memory */ @@ -1242,32 +1286,108 @@ _dbus_hash_table_insert_int (DBusHashTable *table, * @param value the hash entry value. */ dbus_bool_t -_dbus_hash_table_insert_pointer (DBusHashTable *table, - void *key, +_dbus_hash_table_insert_uintptr (DBusHashTable *table, + uintptr_t key, void *value) { DBusHashEntry *entry; - _dbus_assert (table->key_type == DBUS_HASH_POINTER); + _dbus_assert (table->key_type == DBUS_HASH_UINTPTR); - entry = (* table->find_function) (table, key, TRUE, NULL); + entry = (* table->find_function) (table, (void*) key, TRUE, NULL, NULL); if (entry == NULL) return FALSE; /* no memory */ - if (table->free_key_function && entry->key != key) + if (table->free_key_function && entry->key != (void*) key) (* table->free_key_function) (entry->key); if (table->free_value_function && entry->value != value) (* table->free_value_function) (entry->value); - entry->key = key; + entry->key = (void*) key; entry->value = value; return TRUE; } /** + * Preallocate an opaque data blob that allows us to insert into the + * hash table at a later time without allocating any memory. + * + * @param table the hash table + * @returns the preallocated data, or #NULL if no memory + */ +DBusPreallocatedHash* +_dbus_hash_table_preallocate_entry (DBusHashTable *table) +{ + DBusHashEntry *entry; + + entry = alloc_entry (table); + + return (DBusPreallocatedHash*) entry; +} + +/** + * Frees an opaque DBusPreallocatedHash that was *not* used + * in order to insert into the hash table. + * + * @param table the hash table + * @param preallocated the preallocated data + */ +void +_dbus_hash_table_free_preallocated_entry (DBusHashTable *table, + DBusPreallocatedHash *preallocated) +{ + DBusHashEntry *entry; + + _dbus_assert (preallocated != NULL); + + entry = (DBusHashEntry*) preallocated; + + /* Don't use free_entry(), since this entry has no key/data */ + _dbus_mem_pool_dealloc (table->entry_pool, entry); +} + +/** + * Inserts a string-keyed entry into the hash table, using a + * preallocated data block from + * _dbus_hash_table_preallocate_entry(). This function cannot fail due + * to lack of memory. The DBusPreallocatedHash object is consumed and + * should not be reused or freed. Otherwise this function works + * just like _dbus_hash_table_insert_string(). + * + * @param table the hash table + * @param preallocated the preallocated data + * @param key the hash key + * @param value the value + */ +void +_dbus_hash_table_insert_string_preallocated (DBusHashTable *table, + DBusPreallocatedHash *preallocated, + char *key, + void *value) +{ + DBusHashEntry *entry; + + _dbus_assert (table->key_type == DBUS_HASH_STRING); + _dbus_assert (preallocated != NULL); + + entry = (* table->find_function) (table, key, TRUE, NULL, preallocated); + + _dbus_assert (entry != NULL); + + if (table->free_key_function && entry->key != key) + (* table->free_key_function) (entry->key); + + if (table->free_value_function && entry->value != value) + (* table->free_value_function) (entry->value); + + entry->key = key; + entry->value = value; +} + +/** * Gets the number of hash entries in a hash table. * * @param table the hash table. @@ -1281,7 +1401,7 @@ _dbus_hash_table_get_n_entries (DBusHashTable *table) /** @} */ -#ifdef DBUS_BUILD_TESTS +#ifdef DBUS_ENABLE_EMBEDDED_TESTS #include "dbus-test.h" #include @@ -1316,15 +1436,32 @@ _dbus_hash_test (void) int i; DBusHashTable *table1; DBusHashTable *table2; + DBusHashTable *table3; DBusHashIter iter; #define N_HASH_KEYS 5000 - char keys[N_HASH_KEYS][128]; + char **keys; + dbus_bool_t ret = FALSE; + + keys = dbus_new (char *, N_HASH_KEYS); + if (keys == NULL) + _dbus_assert_not_reached ("no memory"); + + for (i = 0; i < N_HASH_KEYS; i++) + { + keys[i] = dbus_malloc (128); + + if (keys[i] == NULL) + _dbus_assert_not_reached ("no memory"); + } printf ("Computing test hash keys...\n"); i = 0; while (i < N_HASH_KEYS) { - sprintf (keys[i], "Hash key %d", i); + int len; + + len = sprintf (keys[i], "Hash key %d", i); + _dbus_assert (*(keys[i] + len) == '\0'); ++i; } printf ("... done.\n"); @@ -1332,12 +1469,17 @@ _dbus_hash_test (void) table1 = _dbus_hash_table_new (DBUS_HASH_STRING, dbus_free, dbus_free); if (table1 == NULL) - return FALSE; + goto out; table2 = _dbus_hash_table_new (DBUS_HASH_INT, NULL, dbus_free); if (table2 == NULL) - return FALSE; + goto out; + + table3 = _dbus_hash_table_new (DBUS_HASH_UINTPTR, + NULL, dbus_free); + if (table3 == NULL) + goto out; /* Insert and remove a bunch of stuff, counting the table in between * to be sure it's not broken and that iteration works @@ -1350,25 +1492,34 @@ _dbus_hash_test (void) key = _dbus_strdup (keys[i]); if (key == NULL) - return FALSE; + goto out; value = _dbus_strdup ("Value!"); if (value == NULL) - return FALSE; + goto out; if (!_dbus_hash_table_insert_string (table1, key, value)) - return FALSE; + goto out; value = _dbus_strdup (keys[i]); if (value == NULL) - return FALSE; + goto out; if (!_dbus_hash_table_insert_int (table2, i, value)) - return FALSE; + goto out; + + value = _dbus_strdup (keys[i]); + if (value == NULL) + goto out; + if (!_dbus_hash_table_insert_uintptr (table3, + i, value)) + goto out; + _dbus_assert (count_entries (table1) == i + 1); _dbus_assert (count_entries (table2) == i + 1); + _dbus_assert (count_entries (table3) == i + 1); value = _dbus_hash_table_lookup_string (table1, keys[i]); _dbus_assert (value != NULL); @@ -1377,7 +1528,11 @@ _dbus_hash_test (void) value = _dbus_hash_table_lookup_int (table2, i); _dbus_assert (value != NULL); _dbus_assert (strcmp (value, keys[i]) == 0); - + + value = _dbus_hash_table_lookup_uintptr (table3, i); + _dbus_assert (value != NULL); + _dbus_assert (strcmp (value, keys[i]) == 0); + ++i; } @@ -1389,19 +1544,25 @@ _dbus_hash_test (void) _dbus_hash_table_remove_int (table2, i); + _dbus_hash_table_remove_uintptr (table3, i); + _dbus_assert (count_entries (table1) == i); _dbus_assert (count_entries (table2) == i); + _dbus_assert (count_entries (table3) == i); --i; } _dbus_hash_table_ref (table1); _dbus_hash_table_ref (table2); + _dbus_hash_table_ref (table3); _dbus_hash_table_unref (table1); _dbus_hash_table_unref (table2); + _dbus_hash_table_unref (table3); _dbus_hash_table_unref (table1); _dbus_hash_table_unref (table2); - + _dbus_hash_table_unref (table3); + table3 = NULL; /* Insert a bunch of stuff then check * that iteration works correctly (finds the right @@ -1410,12 +1571,12 @@ _dbus_hash_test (void) table1 = _dbus_hash_table_new (DBUS_HASH_STRING, dbus_free, dbus_free); if (table1 == NULL) - return FALSE; + goto out; table2 = _dbus_hash_table_new (DBUS_HASH_INT, NULL, dbus_free); if (table2 == NULL) - return FALSE; + goto out; i = 0; while (i < 5000) @@ -1425,22 +1586,22 @@ _dbus_hash_test (void) key = _dbus_strdup (keys[i]); if (key == NULL) - return FALSE; + goto out; value = _dbus_strdup ("Value!"); if (value == NULL) - return FALSE; + goto out; if (!_dbus_hash_table_insert_string (table1, key, value)) - return FALSE; + goto out; value = _dbus_strdup (keys[i]); if (value == NULL) - return FALSE; + goto out; if (!_dbus_hash_table_insert_int (table2, i, value)) - return FALSE; + goto out; _dbus_assert (count_entries (table1) == i + 1); _dbus_assert (count_entries (table2) == i + 1); @@ -1461,7 +1622,7 @@ _dbus_hash_test (void) value = _dbus_strdup ("Different value!"); if (value == NULL) - return FALSE; + goto out; _dbus_hash_iter_set_value (&iter, value); @@ -1489,7 +1650,7 @@ _dbus_hash_test (void) value = _dbus_strdup ("Different value!"); if (value == NULL) - return FALSE; + goto out; _dbus_hash_iter_set_value (&iter, value); @@ -1516,15 +1677,15 @@ _dbus_hash_test (void) key = _dbus_strdup (keys[i]); if (key == NULL) - return FALSE; + goto out; value = _dbus_strdup ("Value!"); if (value == NULL) - return FALSE; + goto out; if (!_dbus_hash_table_insert_string (table1, key, value)) - return FALSE; + goto out; ++i; } @@ -1537,20 +1698,20 @@ _dbus_hash_test (void) key = _dbus_strdup (keys[i]); if (key == NULL) - return FALSE; + goto out; value = _dbus_strdup ("Value!"); if (value == NULL) - return FALSE; + goto out; if (!_dbus_hash_table_remove_string (table1, keys[i])) - return FALSE; + goto out; if (!_dbus_hash_table_insert_string (table1, key, value)) - return FALSE; + goto out; if (!_dbus_hash_table_remove_string (table1, keys[i])) - return FALSE; + goto out; _dbus_assert (_dbus_hash_table_get_n_entries (table1) == i); @@ -1568,12 +1729,12 @@ _dbus_hash_test (void) table1 = _dbus_hash_table_new (DBUS_HASH_STRING, dbus_free, dbus_free); if (table1 == NULL) - return FALSE; + goto out; table2 = _dbus_hash_table_new (DBUS_HASH_INT, NULL, dbus_free); if (table2 == NULL) - return FALSE; + goto out; i = 0; while (i < 3000) @@ -1583,24 +1744,24 @@ _dbus_hash_test (void) key = _dbus_strdup (keys[i]); if (key == NULL) - return FALSE; + goto out; value = _dbus_strdup ("Value!"); if (value == NULL) - return FALSE; + goto out; if (!_dbus_hash_iter_lookup (table1, key, TRUE, &iter)) - return FALSE; + goto out; _dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL); _dbus_hash_iter_set_value (&iter, value); value = _dbus_strdup (keys[i]); if (value == NULL) - return FALSE; + goto out; if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), TRUE, &iter)) - return FALSE; + goto out; _dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL); _dbus_hash_iter_set_value (&iter, value); @@ -1608,7 +1769,7 @@ _dbus_hash_test (void) _dbus_assert (count_entries (table2) == i + 1); if (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter)) - return FALSE; + goto out; value = _dbus_hash_iter_get_value (&iter); _dbus_assert (value != NULL); @@ -1621,7 +1782,7 @@ _dbus_hash_test (void) ; if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter)) - return FALSE; + goto out; value = _dbus_hash_iter_get_value (&iter); _dbus_assert (value != NULL); @@ -1656,8 +1817,15 @@ _dbus_hash_test (void) _dbus_hash_table_unref (table1); _dbus_hash_table_unref (table2); + ret = TRUE; + + out: + for (i = 0; i < N_HASH_KEYS; i++) + dbus_free (keys[i]); + + dbus_free (keys); - return TRUE; + return ret; } -#endif /* DBUS_BUILD_TESTS */ +#endif /* DBUS_ENABLE_EMBEDDED_TESTS */