On Tue, 2009-12-08 at 13:26 -0500, John Dennis wrote: > On 12/08/2009 01:08 PM, Simo Sorce wrote: > > A delete callback may need to get information beyond the single hash > > entry. Pass in a private pointer so the caller can pass whatever private > > context to the delete callback. > > > > Simo. > > Am I missing something? This doesn't address Dmitri's issue.
As discussed privately I changed the patch to pass more data, to the delete_callback. This should also address Dmitri's use case. Also attached another patch to document the changes. Simo. -- Simo Sorce * Red Hat, Inc * New York
>From eac9fe0b26cebfe07e02729667a3aba202d0a9d4 Mon Sep 17 00:00:00 2001 From: Simo Sorce <sso...@redhat.com> Date: Tue, 8 Dec 2009 14:12:03 -0500 Subject: [PATCH] Add comments to document latest changes --- common/dhash/dhash.h | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/common/dhash/dhash.h b/common/dhash/dhash.h index 72b054e..47f9673 100644 --- a/common/dhash/dhash.h +++ b/common/dhash/dhash.h @@ -177,6 +177,9 @@ const char* hash_error_string(int error); * parameter is a pointer to a function which will be called just prior to a * hash entry being deleted. This is useful when the hash value has items which * may need to be disposed of. The delete_callback may be NULL. + * The delete_private_data is data passed to the delete_callback, this way + * custom callbacks can have a private context to reach data they need to use + * before performning their operations. delete_private_data may be NULL. */ int hash_create(unsigned long count, hash_table_t **tbl, hash_delete_callback *delete_callback, @@ -194,6 +197,10 @@ int hash_create(unsigned long count, hash_table_t **tbl, * is greater than the max_load_factor the table is expanded. * alloc_func: function pointer for allocation * free_func: funciton pointer for freeing memory allocated with alloc_func + * alloc_private data: data passed to the alloc and free functions so that + * custom functions can refernce other private data they may + * need during their execution without having to use global + * variables. * * Note directory_bits + segment_bits must be <= number of bits in unsigned long */ -- 1.6.2.5
>From 17a4016b76aaf352dad91575840aa09605ad430e Mon Sep 17 00:00:00 2001 From: Simo Sorce <sso...@redhat.com> Date: Tue, 8 Dec 2009 14:05:22 -0500 Subject: [PATCH 1/2] dhash: Add private pointer for delete callback Also pass a flag to the delete callback to tell it if this is a normal entry removal or we are cleaning up the tbale definitively. --- common/dhash/dhash.c | 23 +++++++++++++++++------ common/dhash/dhash.h | 15 ++++++++++++--- common/dhash/dhash_example.c | 5 +++-- common/dhash/dhash_test.c | 5 +++-- server/responder/common/responder_dp.c | 2 +- server/util/find_uid.c | 3 ++- 6 files changed, 38 insertions(+), 15 deletions(-) diff --git a/common/dhash/dhash.c b/common/dhash/dhash.c index 07815ec..fb024c8 100644 --- a/common/dhash/dhash.c +++ b/common/dhash/dhash.c @@ -36,6 +36,11 @@ #define halloc(table, size) table->halloc(size, table->halloc_pvt) #define hfree(table, ptr) table->hfree(ptr, table->halloc_pvt) +#define hdelete_callback(table, type, entry) do { \ + if (table->delete_callback) { \ + table->delete_callback(entry, type, table->delete_pvt); \ + } \ +} while(0) /*****************************************************************************/ /************************** Internal Type Definitions ************************/ @@ -59,7 +64,8 @@ struct hash_table_str { unsigned int directory_size_shift; unsigned long segment_size; unsigned int segment_size_shift; - hash_delete_callback delete_callback; + hash_delete_callback *delete_callback; + void *delete_pvt; hash_alloc_func *halloc; hash_free_func *hfree; void *halloc_pvt; @@ -457,10 +463,13 @@ const char* hash_error_string(int error) int hash_create(unsigned long count, hash_table_t **tbl, - hash_delete_callback delete_callback) + hash_delete_callback *delete_callback, + void *delete_private_data) { return hash_create_ex(count, tbl, 0, 0, 0, 0, - NULL, NULL, NULL, delete_callback); + NULL, NULL, NULL, + delete_callback, + delete_private_data); } int hash_create_ex(unsigned long count, hash_table_t **tbl, @@ -471,7 +480,8 @@ int hash_create_ex(unsigned long count, hash_table_t **tbl, hash_alloc_func *alloc_func, hash_free_func *free_func, void *alloc_private_data, - hash_delete_callback delete_callback) + hash_delete_callback *delete_callback, + void *delete_private_data) { unsigned long i; unsigned int n_addr_bits; @@ -526,6 +536,7 @@ int hash_create_ex(unsigned long count, hash_table_t **tbl, table->p = 0; table->entry_count = 0; table->delete_callback = delete_callback; + table->delete_pvt = delete_private_data; /* * Allocate initial 'i' segments of buckets @@ -585,7 +596,7 @@ int hash_destroy(hash_table_t *table) p = s[j]; while (p != NULL) { q = p->next; - if (table->delete_callback) table->delete_callback(&p->entry); + hdelete_callback(table, HASH_TABLE_DESTROY, &p->entry); if (p->entry.key.type == HASH_KEY_STRING) { hfree(table, (char *)p->entry.key.str); } @@ -935,7 +946,7 @@ int hash_delete(hash_table_t *table, hash_key_t *key) lookup(table, key, &element, &chain); if (element) { - if (table->delete_callback) table->delete_callback(&element->entry); + hdelete_callback(table, HASH_ENTRY_DESTROY, &element->entry); *chain = element->next; /* remove from chain */ /* * Table too sparse? diff --git a/common/dhash/dhash.h b/common/dhash/dhash.h index a8b0d83..72b054e 100644 --- a/common/dhash/dhash.h +++ b/common/dhash/dhash.h @@ -97,6 +97,12 @@ typedef enum HASH_VALUE_DOUBLE } hash_value_enum; +typedef enum +{ + HASH_TABLE_DESTROY, + HASH_ENTRY_DESTROY +} hash_destroy_enum; + typedef struct hash_key_t { hash_key_enum type; union { @@ -135,7 +141,8 @@ typedef struct hash_statistics_t { /* typedef's for callback based iteration */ typedef bool(*hash_iterate_callback)(hash_entry_t *item, void *user_data); -typedef void (*hash_delete_callback)(hash_entry_t *item); +typedef void (hash_delete_callback)(hash_entry_t *item, + hash_destroy_enum type, void *pvt); /* typedef's for iteration object based iteration */ struct hash_iter_context_t; @@ -172,7 +179,8 @@ const char* hash_error_string(int error); * may need to be disposed of. The delete_callback may be NULL. */ int hash_create(unsigned long count, hash_table_t **tbl, - hash_delete_callback delete_callback); + hash_delete_callback *delete_callback, + void *delete_private_data); /* * Create a new hash table and fine tune it's configurable parameters. @@ -197,7 +205,8 @@ int hash_create_ex(unsigned long count, hash_table_t **tbl, hash_alloc_func *alloc_func, hash_free_func *free_func, void *alloc_private_data, - hash_delete_callback delete_callback); + hash_delete_callback *delete_callback, + void *delete_private_data); #ifdef HASH_STATISTICS /* diff --git a/common/dhash/dhash_example.c b/common/dhash/dhash_example.c index b7de623..7ed01d7 100644 --- a/common/dhash/dhash_example.c +++ b/common/dhash/dhash_example.c @@ -9,7 +9,7 @@ struct my_data_t { char bar[128]; }; -void delete_callback(hash_entry_t *entry) +void delete_callback(hash_entry_t *entry, hash_destroy_enum type, void *pvt) { if (entry->value.type == HASH_VALUE_PTR) free(entry->value.ptr); } @@ -45,7 +45,8 @@ int main(int argc, char **argv) unsigned long count; /* Create a hash table */ - if ((error = hash_create(10, &table, delete_callback)) != HASH_SUCCESS) { + error = hash_create(10, &table, delete_callback, NULL); + if (error != HASH_SUCCESS) { fprintf(stderr, "cannot create hash table (%s)\n", hash_error_string(error)); return error; } diff --git a/common/dhash/dhash_test.c b/common/dhash/dhash_test.c index fedfa66..27eb88d 100644 --- a/common/dhash/dhash_test.c +++ b/common/dhash/dhash_test.c @@ -98,7 +98,7 @@ bool callback(hash_entry_t *item, void *user_data) return true; } -void delete_callback(hash_entry_t *item) +void delete_callback(hash_entry_t *item, hash_destroy_enum type, void *pvt) { if (item->value.type == HASH_VALUE_PTR) free(item->value.ptr); } @@ -188,7 +188,8 @@ int main(int argc, char **argv) if ((status = hash_create_ex(1, &table, directory_bits, segment_bits, min_load_factor, max_load_factor, - NULL, NULL, NULL, delete_callback)) != HASH_SUCCESS) { + NULL, NULL, NULL, + delete_callback, NULL)) != HASH_SUCCESS) { fprintf(stderr, "table creation failed at line %d (%s)\n", __LINE__, error_string(status)); exit(1); } diff --git a/server/responder/common/responder_dp.c b/server/responder/common/responder_dp.c index 1fe1d95..305f6d8 100644 --- a/server/responder/common/responder_dp.c +++ b/server/responder/common/responder_dp.c @@ -286,7 +286,7 @@ int sss_dp_send_acct_req(struct resp_ctx *rctx, TALLOC_CTX *callback_memctx, if (dp_requests == NULL) { /* Create a hash table to handle queued update requests */ - ret = hash_create(10, &dp_requests, NULL); + ret = hash_create(10, &dp_requests, NULL, NULL); if (ret != HASH_SUCCESS) { fprintf(stderr, "cannot create hash table (%s)\n", hash_error_string(ret)); return EIO; diff --git a/server/util/find_uid.c b/server/util/find_uid.c index 09c47b3..63907f1 100644 --- a/server/util/find_uid.c +++ b/server/util/find_uid.c @@ -263,7 +263,8 @@ errno_t get_uid_table(TALLOC_CTX *mem_ctx, hash_table_t **table) int ret; ret = hash_create_ex(INITIAL_TABLE_SIZE, table, 0, 0, 0, 0, - hash_talloc, hash_talloc_free, mem_ctx, NULL); + hash_talloc, hash_talloc_free, mem_ctx, + NULL, NULL); if (ret != HASH_SUCCESS) { DEBUG(1, ("hash_create_ex failed [%s]\n", hash_error_string(ret))); return ENOMEM; -- 1.6.2.5
_______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://fedorahosted.org/mailman/listinfo/sssd-devel