@@ -1383,8 +1383,8 @@ bounded_lru_cache_update_lock_held(lru_cache_object *self,
13831383 this same key, then this setitem call will update the cache dict
13841384 with this new link, leaving the old link as an orphan (i.e. not
13851385 having a cache dict entry that refers to it). */
1386- if (_PyDict_SetItem_KnownHash ( self -> cache , key , ( PyObject * ) link ,
1387- hash ) < 0 ) {
1386+ if (_PyDict_SetItem_KnownHash_LockHeld (( PyDictObject * ) self -> cache , key ,
1387+ ( PyObject * ) link , hash ) < 0 ) {
13881388 Py_DECREF (link );
13891389 return NULL ;
13901390 }
@@ -1453,8 +1453,8 @@ bounded_lru_cache_update_lock_held(lru_cache_object *self,
14531453 for successful insertion in the cache dict before adding the
14541454 link to the linked list. Otherwise, the potentially reentrant
14551455 __eq__ call could cause the then orphan link to be visited. */
1456- if (_PyDict_SetItem_KnownHash ( self -> cache , key , ( PyObject * ) link ,
1457- hash ) < 0 ) {
1456+ if (_PyDict_SetItem_KnownHash_LockHeld (( PyDictObject * ) self -> cache , key ,
1457+ ( PyObject * ) link , hash ) < 0 ) {
14581458 /* Somehow the cache dict update failed. We no longer can
14591459 restore the old link. Let the error propagate upward and
14601460 leave the cache short one link. */
@@ -1689,7 +1689,13 @@ _functools__lru_cache_wrapper_cache_clear_impl(PyObject *self)
16891689 lru_list_elem * list = lru_cache_unlink_list (_self );
16901690 FT_ATOMIC_STORE_SSIZE_RELAXED (_self -> hits , 0 );
16911691 FT_ATOMIC_STORE_SSIZE_RELAXED (_self -> misses , 0 );
1692- PyDict_Clear (_self -> cache );
1692+ if (_self -> wrapper == bounded_lru_cache_wrapper ) {
1693+ /* The critical section on the lru cache itself protects the dictionary
1694+ for bounded_lru_cache instances. */
1695+ _PyDict_Clear_LockHeld (_self -> cache );
1696+ } else {
1697+ PyDict_Clear (_self -> cache );
1698+ }
16931699 lru_cache_clear_list (list );
16941700 Py_RETURN_NONE ;
16951701}
0 commit comments