@@ -685,9 +685,15 @@ type_cache_clear(struct type_cache *cache, PyObject *value)
685685{
686686 for (Py_ssize_t i = 0 ; i < (1 << MCACHE_SIZE_EXP ); i ++ ) {
687687 struct type_cache_entry * entry = & cache -> hashtable [i ];
688+ #ifdef Py_GIL_DISABLED
689+ _PySeqLock_LockWrite (& entry -> sequence );
690+ #endif
688691 entry -> version = 0 ;
689692 Py_XSETREF (entry -> name , _Py_XNewRef (value ));
690693 entry -> value = NULL ;
694+ #ifdef Py_GIL_DISABLED
695+ _PySeqLock_UnlockWrite (& entry -> sequence );
696+ #endif
691697 }
692698}
693699
@@ -4885,6 +4891,8 @@ update_cache(struct type_cache_entry *entry, PyObject *name, unsigned int versio
48854891 entry -> value = value ; /* borrowed */
48864892 assert (_PyASCIIObject_CAST (name )-> hash != -1 );
48874893 OBJECT_STAT_INC_COND (type_cache_collisions , entry -> name != Py_None && entry -> name != name );
4894+ // We're releasing this under the lock for simplicity sake because it's always a
4895+ // exact unicode object or Py_None so it's safe to do so.
48884896 Py_SETREF (entry -> name , Py_NewRef (name ));
48894897}
48904898
@@ -4915,15 +4923,17 @@ update_cache_gil_disabled(struct type_cache_entry *entry, PyObject *name,
49154923
49164924#endif
49174925
4918- void _PyTypes_AfterFork () {
4926+ void
4927+ _PyTypes_AfterFork ()
4928+ {
49194929#ifdef Py_GIL_DISABLED
49204930 struct type_cache * cache = get_type_cache ();
4921- for (int i = 0 ; i < 1 << MCACHE_SIZE_EXP ; i ++ ) {
4931+ for (Py_ssize_t i = 0 ; i < ( 1 << MCACHE_SIZE_EXP ) ; i ++ ) {
49224932 struct type_cache_entry * entry = & cache -> hashtable [i ];
49234933 if (_PySeqLock_AfterFork (& entry -> sequence )) {
49244934 // Entry was in the process of updating while forking, clear it...
49254935 entry -> value = NULL ;
4926- entry -> name = NULL ;
4936+ Py_SETREF ( entry -> name , Py_None ) ;
49274937 entry -> version = 0 ;
49284938 }
49294939 }
@@ -4987,6 +4997,7 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
49874997 if (MCACHE_CACHEABLE_NAME (name )) {
49884998 has_version = assign_version_tag (interp , type );
49894999 version = type -> tp_version_tag ;
5000+ assert (!has_version || _PyType_HasFeature (type , Py_TPFLAGS_VALID_VERSION_TAG ));
49905001 }
49915002 END_TYPE_LOCK ()
49925003
@@ -5012,8 +5023,7 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
50125023#else
50135024 update_cache (entry , name , version , res );
50145025#endif
5015- assert (_PyType_HasFeature (type , Py_TPFLAGS_VALID_VERSION_TAG ));
5016- }
5026+ }
50175027 return res ;
50185028}
50195029
@@ -9486,13 +9496,13 @@ slot_bf_getbuffer(PyObject *self, Py_buffer *buffer, int flags)
94869496 return -1 ;
94879497}
94889498
9489- static int
9490- releasebuffer_maybe_call_super_unlocked (PyObject * self , Py_buffer * buffer , releasebufferproc * base_releasebuffer )
9499+ static releasebufferproc
9500+ releasebuffer_maybe_call_super_unlocked (PyObject * self , Py_buffer * buffer )
94919501{
94929502 PyTypeObject * self_type = Py_TYPE (self );
94939503 PyObject * mro = lookup_tp_mro (self_type );
94949504 if (mro == NULL ) {
9495- return -1 ;
9505+ return NULL ;
94969506 }
94979507
94989508 assert (PyTuple_Check (mro ));
@@ -9506,9 +9516,8 @@ releasebuffer_maybe_call_super_unlocked(PyObject *self, Py_buffer *buffer, relea
95069516 }
95079517 i ++ ; /* skip self_type */
95089518 if (i >= n )
9509- return -1 ;
9519+ return NULL ;
95109520
9511- * base_releasebuffer = NULL ;
95129521 for (; i < n ; i ++ ) {
95139522 PyObject * obj = PyTuple_GET_ITEM (mro , i );
95149523 if (!PyType_Check (obj )) {
@@ -9518,28 +9527,25 @@ releasebuffer_maybe_call_super_unlocked(PyObject *self, Py_buffer *buffer, relea
95189527 if (base_type -> tp_as_buffer != NULL
95199528 && base_type -> tp_as_buffer -> bf_releasebuffer != NULL
95209529 && base_type -> tp_as_buffer -> bf_releasebuffer != slot_bf_releasebuffer ) {
9521- * base_releasebuffer = base_type -> tp_as_buffer -> bf_releasebuffer ;
9522- break ;
9530+ return base_type -> tp_as_buffer -> bf_releasebuffer ;
95239531 }
95249532 }
95259533
9526- return 0 ;
9534+ return NULL ;
95279535}
95289536
9529- static int
9537+ static void
95309538releasebuffer_maybe_call_super (PyObject * self , Py_buffer * buffer )
95319539{
9532- int res ;
95339540 releasebufferproc base_releasebuffer ;
95349541
95359542 BEGIN_TYPE_LOCK ();
9536- res = releasebuffer_maybe_call_super_unlocked (self , buffer , & base_releasebuffer );
9543+ base_releasebuffer = releasebuffer_maybe_call_super_unlocked (self , buffer );
95379544 END_TYPE_LOCK ();
95389545
9539- if (res == 0 ) {
9546+ if (base_releasebuffer != NULL ) {
95409547 base_releasebuffer (self , buffer );
95419548 }
9542- return res ;
95439549}
95449550
95459551static void
@@ -9616,11 +9622,7 @@ static void
96169622slot_bf_releasebuffer (PyObject * self , Py_buffer * buffer )
96179623{
96189624 releasebuffer_call_python (self , buffer );
9619- if (releasebuffer_maybe_call_super (self , buffer ) < 0 ) {
9620- if (PyErr_Occurred ()) {
9621- PyErr_WriteUnraisable (self );
9622- }
9623- }
9625+ releasebuffer_maybe_call_super (self , buffer );
96249626}
96259627
96269628static PyObject *
0 commit comments