@@ -685,9 +685,15 @@ type_cache_clear(struct type_cache *cache, PyObject *value)
685
685
{
686
686
for (Py_ssize_t i = 0 ; i < (1 << MCACHE_SIZE_EXP ); i ++ ) {
687
687
struct type_cache_entry * entry = & cache -> hashtable [i ];
688
+ #ifdef Py_GIL_DISABLED
689
+ _PySeqLock_LockWrite (& entry -> sequence );
690
+ #endif
688
691
entry -> version = 0 ;
689
692
Py_XSETREF (entry -> name , _Py_XNewRef (value ));
690
693
entry -> value = NULL ;
694
+ #ifdef Py_GIL_DISABLED
695
+ _PySeqLock_UnlockWrite (& entry -> sequence );
696
+ #endif
691
697
}
692
698
}
693
699
@@ -4885,6 +4891,8 @@ update_cache(struct type_cache_entry *entry, PyObject *name, unsigned int versio
4885
4891
entry -> value = value ; /* borrowed */
4886
4892
assert (_PyASCIIObject_CAST (name )-> hash != -1 );
4887
4893
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.
4888
4896
Py_SETREF (entry -> name , Py_NewRef (name ));
4889
4897
}
4890
4898
@@ -4915,15 +4923,17 @@ update_cache_gil_disabled(struct type_cache_entry *entry, PyObject *name,
4915
4923
4916
4924
#endif
4917
4925
4918
- void _PyTypes_AfterFork () {
4926
+ void
4927
+ _PyTypes_AfterFork ()
4928
+ {
4919
4929
#ifdef Py_GIL_DISABLED
4920
4930
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 ++ ) {
4922
4932
struct type_cache_entry * entry = & cache -> hashtable [i ];
4923
4933
if (_PySeqLock_AfterFork (& entry -> sequence )) {
4924
4934
// Entry was in the process of updating while forking, clear it...
4925
4935
entry -> value = NULL ;
4926
- entry -> name = NULL ;
4936
+ Py_SETREF ( entry -> name , Py_None ) ;
4927
4937
entry -> version = 0 ;
4928
4938
}
4929
4939
}
@@ -4987,6 +4997,7 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
4987
4997
if (MCACHE_CACHEABLE_NAME (name )) {
4988
4998
has_version = assign_version_tag (interp , type );
4989
4999
version = type -> tp_version_tag ;
5000
+ assert (!has_version || _PyType_HasFeature (type , Py_TPFLAGS_VALID_VERSION_TAG ));
4990
5001
}
4991
5002
END_TYPE_LOCK ()
4992
5003
@@ -5012,8 +5023,7 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
5012
5023
#else
5013
5024
update_cache (entry , name , version , res );
5014
5025
#endif
5015
- assert (_PyType_HasFeature (type , Py_TPFLAGS_VALID_VERSION_TAG ));
5016
- }
5026
+ }
5017
5027
return res ;
5018
5028
}
5019
5029
@@ -9486,13 +9496,13 @@ slot_bf_getbuffer(PyObject *self, Py_buffer *buffer, int flags)
9486
9496
return -1 ;
9487
9497
}
9488
9498
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 )
9491
9501
{
9492
9502
PyTypeObject * self_type = Py_TYPE (self );
9493
9503
PyObject * mro = lookup_tp_mro (self_type );
9494
9504
if (mro == NULL ) {
9495
- return -1 ;
9505
+ return NULL ;
9496
9506
}
9497
9507
9498
9508
assert (PyTuple_Check (mro ));
@@ -9506,9 +9516,8 @@ releasebuffer_maybe_call_super_unlocked(PyObject *self, Py_buffer *buffer, relea
9506
9516
}
9507
9517
i ++ ; /* skip self_type */
9508
9518
if (i >= n )
9509
- return -1 ;
9519
+ return NULL ;
9510
9520
9511
- * base_releasebuffer = NULL ;
9512
9521
for (; i < n ; i ++ ) {
9513
9522
PyObject * obj = PyTuple_GET_ITEM (mro , i );
9514
9523
if (!PyType_Check (obj )) {
@@ -9518,28 +9527,25 @@ releasebuffer_maybe_call_super_unlocked(PyObject *self, Py_buffer *buffer, relea
9518
9527
if (base_type -> tp_as_buffer != NULL
9519
9528
&& base_type -> tp_as_buffer -> bf_releasebuffer != NULL
9520
9529
&& 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 ;
9523
9531
}
9524
9532
}
9525
9533
9526
- return 0 ;
9534
+ return NULL ;
9527
9535
}
9528
9536
9529
- static int
9537
+ static void
9530
9538
releasebuffer_maybe_call_super (PyObject * self , Py_buffer * buffer )
9531
9539
{
9532
- int res ;
9533
9540
releasebufferproc base_releasebuffer ;
9534
9541
9535
9542
BEGIN_TYPE_LOCK ();
9536
- res = releasebuffer_maybe_call_super_unlocked (self , buffer , & base_releasebuffer );
9543
+ base_releasebuffer = releasebuffer_maybe_call_super_unlocked (self , buffer );
9537
9544
END_TYPE_LOCK ();
9538
9545
9539
- if (res == 0 ) {
9546
+ if (base_releasebuffer != NULL ) {
9540
9547
base_releasebuffer (self , buffer );
9541
9548
}
9542
- return res ;
9543
9549
}
9544
9550
9545
9551
static void
@@ -9616,11 +9622,7 @@ static void
9616
9622
slot_bf_releasebuffer (PyObject * self , Py_buffer * buffer )
9617
9623
{
9618
9624
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 );
9624
9626
}
9625
9627
9626
9628
static PyObject *
0 commit comments