summaryrefslogtreecommitdiff
path: root/src/dict.h
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2013-08-16 14:08:04 +0200
committerantirez <antirez@gmail.com>2013-08-19 15:00:57 +0200
commit48cde3fe4710b43be6537854ab464b8568616fb8 (patch)
tree692a788c7e752707774a8e8d2c995ab8a5a5832f /src/dict.h
parent739893075675af06b1cc5d782a984e3624e98ff9 (diff)
downloadredis-48cde3fe4710b43be6537854ab464b8568616fb8.tar.gz
dict.c iterator API misuse protection.
dict.c allows the user to create unsafe iterators, that are iterators that will not touch the dictionary data structure in any way, preventing copy on write, but at the same time are limited in their usage. The limitation is that when itearting with an unsafe iterator, no call to other dictionary functions must be done inside the iteration loop, otherwise the dictionary may be incrementally rehashed resulting into missing elements in the set of the elements returned by the iterator. However after introducing this kind of iterators a number of bugs were found due to misuses of the API, and we are still finding bugs about this issue. The bugs are not trivial to track because the effect is just missing elements during the iteartion. This commit introduces auto-detection of the API misuse. The idea is that an unsafe iterator has a contract: from initialization to the release of the iterator the dictionary should not change. So we take a fingerprint of the dictionary state, xoring a few important dict properties when the unsafe iteartor is initialized. We later check when the iterator is released if the fingerprint is still the same. If it is not, we found a misuse of the iterator, as not allowed API calls changed the internal state of the dictionary. This code was checked against a real bug, issue #1240. This is what Redis prints (aborting) when a misuse is detected: Assertion failed: (iter->fingerprint == dictFingerprint(iter->d)), function dictReleaseIterator, file dict.c, line 587.
Diffstat (limited to 'src/dict.h')
-rw-r--r--src/dict.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/src/dict.h b/src/dict.h
index 3a311f171..4d750ae85 100644
--- a/src/dict.h
+++ b/src/dict.h
@@ -88,6 +88,7 @@ typedef struct dictIterator {
dict *d;
int table, index, safe;
dictEntry *entry, *nextEntry;
+ long long fingerprint; /* unsafe iterator fingerprint for misuse detection */
} dictIterator;
/* This is the initial size of every hash table */