@@ -686,9 +686,15 @@ type_cache_clear(struct type_cache *cache, PyObject *value)
686
686
{
687
687
for (Py_ssize_t i = 0 ; i < (1 << MCACHE_SIZE_EXP ); i ++ ) {
688
688
struct type_cache_entry * entry = & cache -> hashtable [i ];
689
+ #ifdef Py_GIL_DISABLED
690
+ _PySeqLock_LockWrite (& entry -> sequence );
691
+ #endif
689
692
entry -> version = 0 ;
690
693
Py_XSETREF (entry -> name , _Py_XNewRef (value ));
691
694
entry -> value = NULL ;
695
+ #ifdef Py_GIL_DISABLED
696
+ _PySeqLock_UnlockWrite (& entry -> sequence );
697
+ #endif
692
698
}
693
699
}
694
700
@@ -4903,6 +4909,8 @@ update_cache(struct type_cache_entry *entry, PyObject *name, unsigned int versio
4903
4909
entry -> value = value ; /* borrowed */
4904
4910
assert (_PyASCIIObject_CAST (name )-> hash != -1 );
4905
4911
OBJECT_STAT_INC_COND (type_cache_collisions , entry -> name != Py_None && entry -> name != name );
4912
+ // We're releasing this under the lock for simplicity sake because it's always a
4913
+ // exact unicode object or Py_None so it's safe to do so.
4906
4914
Py_SETREF (entry -> name , Py_NewRef (name ));
4907
4915
}
4908
4916
@@ -4933,15 +4941,17 @@ update_cache_gil_disabled(struct type_cache_entry *entry, PyObject *name,
4933
4941
4934
4942
#endif
4935
4943
4936
- void _PyTypes_AfterFork () {
4944
+ void
4945
+ _PyTypes_AfterFork ()
4946
+ {
4937
4947
#ifdef Py_GIL_DISABLED
4938
4948
struct type_cache * cache = get_type_cache ();
4939
- for (int i = 0 ; i < 1 << MCACHE_SIZE_EXP ; i ++ ) {
4949
+ for (Py_ssize_t i = 0 ; i < ( 1 << MCACHE_SIZE_EXP ) ; i ++ ) {
4940
4950
struct type_cache_entry * entry = & cache -> hashtable [i ];
4941
4951
if (_PySeqLock_AfterFork (& entry -> sequence )) {
4942
4952
// Entry was in the process of updating while forking, clear it...
4943
4953
entry -> value = NULL ;
4944
- entry -> name = NULL ;
4954
+ Py_SETREF ( entry -> name , Py_None ) ;
4945
4955
entry -> version = 0 ;
4946
4956
}
4947
4957
}
@@ -5005,6 +5015,7 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
5005
5015
if (MCACHE_CACHEABLE_NAME (name )) {
5006
5016
has_version = assign_version_tag (interp , type );
5007
5017
version = type -> tp_version_tag ;
5018
+ assert (!has_version || _PyType_HasFeature (type , Py_TPFLAGS_VALID_VERSION_TAG ));
5008
5019
}
5009
5020
END_TYPE_LOCK ()
5010
5021
@@ -5030,8 +5041,7 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
5030
5041
#else
5031
5042
update_cache (entry , name , version , res );
5032
5043
#endif
5033
- assert (_PyType_HasFeature (type , Py_TPFLAGS_VALID_VERSION_TAG ));
5034
- }
5044
+ }
5035
5045
return res ;
5036
5046
}
5037
5047
@@ -9506,13 +9516,13 @@ slot_bf_getbuffer(PyObject *self, Py_buffer *buffer, int flags)
9506
9516
return -1 ;
9507
9517
}
9508
9518
9509
- static int
9510
- releasebuffer_maybe_call_super_unlocked (PyObject * self , Py_buffer * buffer , releasebufferproc * base_releasebuffer )
9519
+ static releasebufferproc
9520
+ releasebuffer_maybe_call_super_unlocked (PyObject * self , Py_buffer * buffer )
9511
9521
{
9512
9522
PyTypeObject * self_type = Py_TYPE (self );
9513
9523
PyObject * mro = lookup_tp_mro (self_type );
9514
9524
if (mro == NULL ) {
9515
- return -1 ;
9525
+ return NULL ;
9516
9526
}
9517
9527
9518
9528
assert (PyTuple_Check (mro ));
@@ -9526,9 +9536,8 @@ releasebuffer_maybe_call_super_unlocked(PyObject *self, Py_buffer *buffer, relea
9526
9536
}
9527
9537
i ++ ; /* skip self_type */
9528
9538
if (i >= n )
9529
- return -1 ;
9539
+ return NULL ;
9530
9540
9531
- * base_releasebuffer = NULL ;
9532
9541
for (; i < n ; i ++ ) {
9533
9542
PyObject * obj = PyTuple_GET_ITEM (mro , i );
9534
9543
if (!PyType_Check (obj )) {
@@ -9538,28 +9547,25 @@ releasebuffer_maybe_call_super_unlocked(PyObject *self, Py_buffer *buffer, relea
9538
9547
if (base_type -> tp_as_buffer != NULL
9539
9548
&& base_type -> tp_as_buffer -> bf_releasebuffer != NULL
9540
9549
&& base_type -> tp_as_buffer -> bf_releasebuffer != slot_bf_releasebuffer ) {
9541
- * base_releasebuffer = base_type -> tp_as_buffer -> bf_releasebuffer ;
9542
- break ;
9550
+ return base_type -> tp_as_buffer -> bf_releasebuffer ;
9543
9551
}
9544
9552
}
9545
9553
9546
- return 0 ;
9554
+ return NULL ;
9547
9555
}
9548
9556
9549
- static int
9557
+ static void
9550
9558
releasebuffer_maybe_call_super (PyObject * self , Py_buffer * buffer )
9551
9559
{
9552
- int res ;
9553
9560
releasebufferproc base_releasebuffer ;
9554
9561
9555
9562
BEGIN_TYPE_LOCK ();
9556
- res = releasebuffer_maybe_call_super_unlocked (self , buffer , & base_releasebuffer );
9563
+ base_releasebuffer = releasebuffer_maybe_call_super_unlocked (self , buffer );
9557
9564
END_TYPE_LOCK ();
9558
9565
9559
- if (res == 0 ) {
9566
+ if (base_releasebuffer != NULL ) {
9560
9567
base_releasebuffer (self , buffer );
9561
9568
}
9562
- return res ;
9563
9569
}
9564
9570
9565
9571
static void
@@ -9636,11 +9642,7 @@ static void
9636
9642
slot_bf_releasebuffer (PyObject * self , Py_buffer * buffer )
9637
9643
{
9638
9644
releasebuffer_call_python (self , buffer );
9639
- if (releasebuffer_maybe_call_super (self , buffer ) < 0 ) {
9640
- if (PyErr_Occurred ()) {
9641
- PyErr_WriteUnraisable (self );
9642
- }
9643
- }
9645
+ releasebuffer_maybe_call_super (self , buffer );
9644
9646
}
9645
9647
9646
9648
static PyObject *
0 commit comments