From ec7e89026b75b913b23bc141bbe6fa122fa91384 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Fri, 8 Dec 2023 10:14:27 +0000 Subject: [PATCH] LHASH: Fix documentation for doall-delete hazards Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/22981) --- doc/man3/OPENSSL_LH_COMPFUNC.pod | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/doc/man3/OPENSSL_LH_COMPFUNC.pod b/doc/man3/OPENSSL_LH_COMPFUNC.pod index d3091f6a56..331763d0f0 100644 --- a/doc/man3/OPENSSL_LH_COMPFUNC.pod +++ b/doc/man3/OPENSSL_LH_COMPFUNC.pod @@ -157,15 +157,6 @@ For example: /* Then the hash table itself can be deallocated */ lh_TYPE_free(hashtable); -When doing this, be careful if you delete entries from the hash table -in your callbacks: the table may decrease in size, moving the item -that you are currently on down lower in the hash table - this could -cause some entries to be skipped during the iteration. The second -best solution to this problem is to set hash-Edown_load=0 before -you start (which will stop the hash table ever decreasing in size). -The best solution is probably to avoid deleting items from the hash -table inside a "doall" callback! - B_doall_arg>() is the same as B_doall>() except that I will be called with I as the second argument and I should be of type B(B>) (a callback prototype @@ -187,6 +178,23 @@ that is provided by the caller): lh_TYPE_doall_arg(hashtable, LHASH_DOALL_ARG_FN(TYPE_print), BIO, logging_bio); +Note that it is by default B safe to use B_delete>() inside a +callback passed to B_doall>() or B_doall_arg>(). The +reason for this is that deleting an item from the hash table may result in the +hash table being contracted to a smaller size and rehashed. +B_doall>() and B_doall_arg>() are unsafe and will exhibit +undefined behaviour under these conditions, as these functions assume the hash +table size and bucket pointers do not change during the call. + +If it is desired to use B_doall>() or B_doall_arg>() with +B_delete>(), it is essential that you call +B_set_down_load>() with a I argument of 0 first. This +disables hash table contraction and guarantees that it will be safe to delete +items from a hash table during a call to B_doall>() or +B_doall_arg>(). + +It is never safe to call B_insert>() during a call to +B_doall>() or B_doall_arg>(). B_error>() can be used to determine if an error occurred in the last operation.