summaryrefslogtreecommitdiff
path: root/mysys/hash.c
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2017-03-03 13:27:12 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2017-03-03 13:27:12 +0200
commitadc91387e3add6d9c850b7c2a44760deaceb3638 (patch)
treec772c6339d2f715a1a50766e30790307e0658f3e /mysys/hash.c
parentbc28b305e538774eae4152b300cd323e9a724393 (diff)
parent29c776cfd1e560846e394f39d79ae43ff7d70c61 (diff)
downloadmariadb-git-adc91387e3add6d9c850b7c2a44760deaceb3638.tar.gz
Merge 10.0 into 10.1
Diffstat (limited to 'mysys/hash.c')
-rw-r--r--mysys/hash.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/mysys/hash.c b/mysys/hash.c
index dc03ea9a4dc..d59e63bddc4 100644
--- a/mysys/hash.c
+++ b/mysys/hash.c
@@ -114,14 +114,19 @@ my_hash_init2(HASH *hash, uint growth_size, CHARSET_INFO *charset,
static inline void my_hash_free_elements(HASH *hash)
{
+ uint records= hash->records;
+ /*
+ Set records to 0 early to guard against anyone looking at the structure
+ during the free process
+ */
+ hash->records= 0;
if (hash->free)
{
HASH_LINK *data=dynamic_element(&hash->array,0,HASH_LINK*);
- HASH_LINK *end= data + hash->records;
+ HASH_LINK *end= data + records;
while (data < end)
(*hash->free)((data++)->data);
}
- hash->records=0;
}
@@ -518,6 +523,9 @@ my_bool my_hash_insert(HASH *info, const uchar *record)
The record with the same record ptr is removed.
If there is a free-function it's called if record was found.
+ hash->free() is guarantee to be called only after the row has been
+ deleted from the hash and the hash can be reused by other threads.
+
@return
@retval 0 ok
@retval 1 Record not found