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

Reply via email to