@@ -1195,14 +1195,13 @@ infinite_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwd
11951195 Py_DECREF (key );
11961196 return NULL ;
11971197 }
1198- result = _PyDict_GetItem_KnownHash (self -> cache , key , hash );
1199- if (result ) {
1200- Py_INCREF (result );
1198+ int res = _PyDict_GetItemRef_KnownHash ((PyDictObject * )self -> cache , key , hash , & result );
1199+ if (res > 0 ) {
12011200 self -> hits ++ ;
12021201 Py_DECREF (key );
12031202 return result ;
12041203 }
1205- if (PyErr_Occurred () ) {
1204+ if (res < 0 ) {
12061205 Py_DECREF (key );
12071206 return NULL ;
12081207 }
@@ -1281,37 +1280,45 @@ lru_cache_prepend_link(lru_cache_object *self, lru_list_elem *link)
12811280 so that we know the cache is a consistent state.
12821281 */
12831282
1284- static PyObject *
1285- bounded_lru_cache_wrapper (lru_cache_object * self , PyObject * args , PyObject * kwds )
1283+ static int
1284+ bounded_lru_cache_wrapper_pre_call_lock_held (lru_cache_object * self , PyObject * args , PyObject * kwds ,
1285+ PyObject * * result , PyObject * * key , Py_hash_t * hash )
12861286{
12871287 lru_list_elem * link ;
1288- PyObject * key , * result , * testresult ;
1289- Py_hash_t hash ;
12901288
1291- key = lru_cache_make_key (self -> kwd_mark , args , kwds , self -> typed );
1292- if (!key )
1293- return NULL ;
1294- hash = PyObject_Hash (key );
1295- if (hash == -1 ) {
1296- Py_DECREF (key );
1297- return NULL ;
1289+ PyObject * _key = * key = lru_cache_make_key (self -> kwd_mark , args , kwds , self -> typed );
1290+ if (!_key )
1291+ return -1 ;
1292+ Py_hash_t _hash = * hash = PyObject_Hash (_key );
1293+ if (_hash == -1 ) {
1294+ Py_DECREF (_key );
1295+ return -1 ;
12981296 }
1299- link = (lru_list_elem * )_PyDict_GetItem_KnownHash (self -> cache , key , hash );
1297+ link = (lru_list_elem * )_PyDict_GetItem_KnownHash (self -> cache , _key , _hash );
13001298 if (link != NULL ) {
13011299 lru_cache_extract_link (link );
13021300 lru_cache_append_link (self , link );
1303- result = link -> result ;
1301+ * result = link -> result ;
13041302 self -> hits ++ ;
1305- Py_INCREF (result );
1306- Py_DECREF (key );
1307- return result ;
1303+ Py_INCREF (link -> result );
1304+ Py_DECREF (_key );
1305+ return 1 ;
13081306 }
13091307 if (PyErr_Occurred ()) {
1310- Py_DECREF (key );
1311- return NULL ;
1308+ Py_DECREF (_key );
1309+ return -1 ;
13121310 }
13131311 self -> misses ++ ;
1314- result = PyObject_Call (self -> func , args , kwds );
1312+ return 0 ;
1313+ }
1314+
1315+ PyObject *
1316+ bounded_lru_cache_wrapper_post_call_lock_held (lru_cache_object * self ,
1317+ PyObject * result , PyObject * key , Py_hash_t hash )
1318+ {
1319+ lru_list_elem * link ;
1320+ PyObject * testresult ;
1321+
13151322 if (!result ) {
13161323 Py_DECREF (key );
13171324 return NULL ;
@@ -1447,6 +1454,33 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds
14471454 return result ;
14481455}
14491456
1457+ static PyObject *
1458+ bounded_lru_cache_wrapper (lru_cache_object * self , PyObject * args , PyObject * kwds )
1459+ {
1460+ PyObject * key , * result ;
1461+ Py_hash_t hash ;
1462+ int res ;
1463+
1464+ Py_BEGIN_CRITICAL_SECTION (self );
1465+ res = bounded_lru_cache_wrapper_pre_call_lock_held (self , args , kwds , & result , & key , & hash );
1466+ Py_END_CRITICAL_SECTION ();
1467+
1468+ if (res < 0 ) {
1469+ return NULL ;
1470+ }
1471+ if (res > 0 ) {
1472+ return result ;
1473+ }
1474+
1475+ result = PyObject_Call (self -> func , args , kwds );
1476+
1477+ Py_BEGIN_CRITICAL_SECTION (self );
1478+ result = bounded_lru_cache_wrapper_post_call_lock_held (self , result , key , hash );
1479+ Py_END_CRITICAL_SECTION ();
1480+
1481+ return result ;
1482+ }
1483+
14501484static PyObject *
14511485lru_cache_new (PyTypeObject * type , PyObject * args , PyObject * kw )
14521486{
@@ -1579,9 +1613,7 @@ lru_cache_call(PyObject *op, PyObject *args, PyObject *kwds)
15791613{
15801614 lru_cache_object * self = lru_cache_object_CAST (op );
15811615 PyObject * result ;
1582- Py_BEGIN_CRITICAL_SECTION (self );
15831616 result = self -> wrapper (self , args , kwds );
1584- Py_END_CRITICAL_SECTION ();
15851617 return result ;
15861618}
15871619
0 commit comments