Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f2c17a9

Browse files
committed
Fix other re-entrancy nits for the lru_cache.
Keep references for oldkey and oldvalue so they can't trigger a __del__ method to reenter our thread. Move the cache[key]=link step to the end, after the link data is in a consistent state. Under exotic circumstances, the cache[key]=link step could trigger reentrancy (i.e. the key would have to have a hash exactly equal to that for another key in the cache and the key would need a __eq__ method that makes a reentrant call our cached function).
1 parent 0392342 commit f2c17a9

1 file changed

Lines changed: 11 additions & 7 deletions

File tree

Lib/functools.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -267,19 +267,23 @@ def wrapper(*args, **kwds):
267267
# computed result and update the count of misses.
268268
pass
269269
elif full:
270-
# use root to store the new key and result
271-
root[KEY] = key
272-
root[RESULT] = result
273-
cache[key] = root
270+
# use the old root to store the new key and result
271+
oldroot = root
272+
oldroot[KEY] = key
273+
oldroot[RESULT] = result
274274
# empty the oldest link and make it the new root
275-
root = root[NEXT]
276-
del cache[root[KEY]]
275+
root = oldroot[NEXT]
276+
oldkey = root[KEY]
277+
oldvalue = root[RESULT]
277278
root[KEY] = root[RESULT] = None
279+
# now update the cache dictionary for the new links
280+
del cache[oldkey]
281+
cache[key] = oldroot
278282
else:
279283
# put result in a new link at the front of the queue
280284
last = root[PREV]
281285
link = [last, root, key, result]
282-
cache[key] = last[NEXT] = root[PREV] = link
286+
last[NEXT] = root[PREV] = cache[key] = link
283287
currsize += 1
284288
full = (currsize == maxsize)
285289
misses += 1

0 commit comments

Comments
 (0)