mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-23 09:51:57 -05:00
HashTable: Assert on iteration attempt over table during clear/rehash
It doesn't seem sane to try to iterate over a HashTable while it's in the middle of being cleared. Since this might cause strange problems, this patch adds an assertion if an iterator is constructed during clear() or rehash() of a HashTable.
This commit is contained in:
parent
eccc3c3ef0
commit
f10e850644
1 changed files with 7 additions and 1 deletions
|
@ -3,6 +3,7 @@
|
||||||
#include <AK/Assertions.h>
|
#include <AK/Assertions.h>
|
||||||
#include <AK/SinglyLinkedList.h>
|
#include <AK/SinglyLinkedList.h>
|
||||||
#include <AK/StdLibExtras.h>
|
#include <AK/StdLibExtras.h>
|
||||||
|
#include <AK/TemporaryChange.h>
|
||||||
#include <AK/Traits.h>
|
#include <AK/Traits.h>
|
||||||
#include <AK/kstdio.h>
|
#include <AK/kstdio.h>
|
||||||
|
|
||||||
|
@ -59,6 +60,8 @@ private:
|
||||||
, m_is_end(is_end)
|
, m_is_end(is_end)
|
||||||
, m_bucket_iterator(bucket_iterator)
|
, m_bucket_iterator(bucket_iterator)
|
||||||
{
|
{
|
||||||
|
ASSERT(!table.m_clearing);
|
||||||
|
ASSERT(!table.m_rehashing);
|
||||||
if (!is_end && !m_table.is_empty() && !(m_bucket_iterator != BucketIteratorType::universal_end())) {
|
if (!is_end && !m_table.is_empty() && !(m_bucket_iterator != BucketIteratorType::universal_end())) {
|
||||||
m_bucket_iterator = m_table.bucket(0).begin();
|
m_bucket_iterator = m_table.bucket(0).begin();
|
||||||
if (m_bucket_iterator.is_end())
|
if (m_bucket_iterator.is_end())
|
||||||
|
@ -146,7 +149,6 @@ public:
|
||||||
ConstIterator begin() const { return ConstIterator(*this, is_empty()); }
|
ConstIterator begin() const { return ConstIterator(*this, is_empty()); }
|
||||||
ConstIterator end() const { return ConstIterator(*this, true); }
|
ConstIterator end() const { return ConstIterator(*this, true); }
|
||||||
|
|
||||||
|
|
||||||
template<typename Finder>
|
template<typename Finder>
|
||||||
Iterator find(unsigned hash, Finder finder)
|
Iterator find(unsigned hash, Finder finder)
|
||||||
{
|
{
|
||||||
|
@ -221,6 +223,8 @@ private:
|
||||||
|
|
||||||
int m_size { 0 };
|
int m_size { 0 };
|
||||||
int m_capacity { 0 };
|
int m_capacity { 0 };
|
||||||
|
bool m_clearing { false };
|
||||||
|
bool m_rehashing { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename TraitsForT>
|
template<typename T, typename TraitsForT>
|
||||||
|
@ -268,6 +272,7 @@ void HashTable<T, TraitsForT>::set(const T& value)
|
||||||
template<typename T, typename TraitsForT>
|
template<typename T, typename TraitsForT>
|
||||||
void HashTable<T, TraitsForT>::rehash(int new_capacity)
|
void HashTable<T, TraitsForT>::rehash(int new_capacity)
|
||||||
{
|
{
|
||||||
|
TemporaryChange change(m_rehashing, true);
|
||||||
new_capacity *= 2;
|
new_capacity *= 2;
|
||||||
auto* new_buckets = new Bucket[new_capacity];
|
auto* new_buckets = new Bucket[new_capacity];
|
||||||
auto* old_buckets = m_buckets;
|
auto* old_buckets = m_buckets;
|
||||||
|
@ -287,6 +292,7 @@ void HashTable<T, TraitsForT>::rehash(int new_capacity)
|
||||||
template<typename T, typename TraitsForT>
|
template<typename T, typename TraitsForT>
|
||||||
void HashTable<T, TraitsForT>::clear()
|
void HashTable<T, TraitsForT>::clear()
|
||||||
{
|
{
|
||||||
|
TemporaryChange change(m_clearing, true);
|
||||||
if (m_buckets) {
|
if (m_buckets) {
|
||||||
delete[] m_buckets;
|
delete[] m_buckets;
|
||||||
m_buckets = nullptr;
|
m_buckets = nullptr;
|
||||||
|
|
Loading…
Add table
Reference in a new issue