util/IntrusiveHashSet: insert_check() returns the bucket head on success

The list head is a stable value that is guaranteed to be still valid
when insert_commit() gets called.

This fixes a linked list corruption bug in class StaticCache which
occurs when the cache item pointed to by the iterator gets evicted
between insert_check() and insert_commit().
This commit is contained in:
Max Kellermann 2023-07-21 13:34:02 +02:00 committed by Max Kellermann
parent 42d5b05f54
commit aeadae5399
1 changed files with 9 additions and 2 deletions

View File

@ -227,7 +227,11 @@ public:
if (equal(key, i))
return {bucket.iterator_to(i), false};
return {bucket.begin(), true};
/* bucket.end() is a pointer to the bucket's list
head, a stable value that is guaranteed to be still
valid when insert_commit() gets called
eventually */
return {bucket.end(), true};
}
/**
@ -237,7 +241,10 @@ public:
*/
constexpr void insert_commit(bucket_iterator bucket, reference item) noexcept {
++counter;
GetBucket(item).insert(bucket, item);
/* using insert_after() so the new item gets inserted
at the front of the bucket list */
GetBucket(item).insert_after(bucket, item);
}
/**