[DTrace-devel] [PATCH v2 04/11] htab: have dt_htab_destroy del all the elements
Nick Alcock
nick.alcock at oracle.com
Wed Oct 20 11:53:57 PDT 2021
This means that a dt_htab_destroy of a non-empy htab doesn't leak memory
and leave all its former elements full of wild pointers.
Also add some comments to dt_htab_delete given how many mistakes I made
reading it.
Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
---
libdtrace/dt_htab.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/libdtrace/dt_htab.c b/libdtrace/dt_htab.c
index e8004e2b2bca..b8910442cd07 100644
--- a/libdtrace/dt_htab.c
+++ b/libdtrace/dt_htab.c
@@ -73,13 +73,24 @@ dt_htab_t *dt_htab_create(dtrace_hdl_t *dtp, dt_htab_ops_t *ops)
}
/*
- * Destroy a hashtable.
+ * Destroy a hashtable, deleting all its entries first.
*/
void dt_htab_destroy(dtrace_hdl_t *dtp, dt_htab_t *htab)
{
+ size_t i;
+
if (!htab)
return;
+ for (i = 0; i < htab->size; i++) {
+ dt_hbucket_t *bucket = htab->tab[i];
+
+ while (bucket && bucket->head)
+ bucket->head = htab->ops->del(bucket->head,
+ bucket->head);
+ free(bucket);
+ }
+
dt_free(dtp, htab->tab);
dt_free(dtp, htab);
}
@@ -193,6 +204,10 @@ int dt_htab_delete(dt_htab_t *htab, void *entry)
dt_hbucket_t *bucket;
void *head;
+ /*
+ * Find the right bucket in cases of hash collision.
+ */
+
for (bucket = htab->tab[idx]; bucket; bucket = bucket->next) {
if (htab->ops->cmp(bucket->head, entry) == 0)
break;
@@ -201,9 +216,16 @@ int dt_htab_delete(dt_htab_t *htab, void *entry)
if (bucket == NULL)
return -ENOENT;
+ /*
+ * Destroy the specified entry, now known to be in this bucket.
+ */
head = htab->ops->del(bucket->head, entry);
bucket->nentries--;
htab->nentries--;
+
+ /*
+ * Deal with a now-empty bucket.
+ */
if (!head) {
dt_hbucket_t *b = htab->tab[idx];
--
2.33.1.257.g9e0974a4e8
More information about the DTrace-devel
mailing list