diff options
author | Hugo Landau <hlandau@openssl.org> | 2023-12-08 10:14:27 +0000 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2023-12-15 12:46:59 +0100 |
commit | 1a18769d245367545c8bb82b83c49845d9e43907 (patch) | |
tree | 875eba0b53b1d2e52c120b5a5d3dc2de65079343 | |
parent | d802bfbf80bab00123a4a6209f255852b3a10207 (diff) |
LHASH: Fix documentation for doall-delete hazards
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tom Cosgrove <tom.cosgrove@arm.com>
Reviewed-by: Neil Horman <nhorman@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23032)
(cherry picked from commit e91f21193c1b11de775e65b4e209a9fed67a41c1)
-rw-r--r-- | doc/man3/OPENSSL_LH_COMPFUNC.pod | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/doc/man3/OPENSSL_LH_COMPFUNC.pod b/doc/man3/OPENSSL_LH_COMPFUNC.pod index d3bb272c4a..aabd13c522 100644 --- a/doc/man3/OPENSSL_LH_COMPFUNC.pod +++ b/doc/man3/OPENSSL_LH_COMPFUNC.pod @@ -145,15 +145,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-E<gt>down_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<lh_I<TYPE>_doall_arg>() is the same as B<lh_I<TYPE>_doall>() except that I<func> will be called with I<arg> as the second argument and I<func> should be of type B<LHASH_DOALL_ARG_FN>(B<I<TYPE>>) (a callback prototype @@ -175,6 +166,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<not> safe to use B<lh_I<TYPE>_delete>() inside a +callback passed to B<lh_I<TYPE>_doall>() or B<lh_I<TYPE>_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<lh_I<TYPE>_doall>() and B<lh_I<TYPE>_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<lh_I<TYPE>_doall>() or B<lh_I<TYPE>_doall_arg>() with +B<lh_I<TYPE>_delete>(), it is essential that you call +B<lh_I<TYPE>_set_down_load>() with a I<down_load> 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<lh_I<TYPE>_doall>() or +B<lh_I<TYPE>_doall_arg>(). + +It is never safe to call B<lh_I<TYPE>_insert>() during a call to +B<lh_I<TYPE>_doall>() or B<lh_I<TYPE>_doall_arg>(). B<lh_I<TYPE>_error>() can be used to determine if an error occurred in the last operation. |