3
3
#include "Python.h"
4
4
#include "pycore_abstract.h" // _PyIndex_Check()
5
5
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
6
+ #include "pycore_critical_section.h" // _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED()
6
7
#include "pycore_dict.h" // _PyDictViewObject
7
8
#include "pycore_freelist.h" // _Py_FREELIST_FREE(), _Py_FREELIST_POP()
8
9
#include "pycore_pyatomic_ft_wrappers.h"
@@ -72,6 +73,11 @@ static void
72
73
ensure_shared_on_resize (PyListObject * self )
73
74
{
74
75
#ifdef Py_GIL_DISABLED
76
+ // We can't use _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED here because
77
+ // the `CALL_LIST_APPEND` bytecode handler may lock the list without
78
+ // a critical section.
79
+ assert (Py_REFCNT (self ) == 1 || PyMutex_IsLocked (& _PyObject_CAST (self )-> ob_mutex ));
80
+
75
81
// Ensure that the list array is freed using QSBR if we are not the
76
82
// owning thread.
77
83
if (!_Py_IsOwnedByCurrentThread ((PyObject * )self ) &&
@@ -957,10 +963,12 @@ list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
957
963
Py_ssize_t n = PyList_GET_SIZE (a );
958
964
PyObject * copy = list_slice_lock_held (a , 0 , n );
959
965
if (copy == NULL ) {
960
- return -1 ;
966
+ ret = -1 ;
967
+ }
968
+ else {
969
+ ret = list_ass_slice_lock_held (a , ilow , ihigh , copy );
970
+ Py_DECREF (copy );
961
971
}
962
- ret = list_ass_slice_lock_held (a , ilow , ihigh , copy );
963
- Py_DECREF (copy );
964
972
Py_END_CRITICAL_SECTION ();
965
973
}
966
974
else if (v != NULL && PyList_CheckExact (v )) {
@@ -1437,7 +1445,9 @@ PyList_Clear(PyObject *self)
1437
1445
PyErr_BadInternalCall ();
1438
1446
return -1 ;
1439
1447
}
1448
+ Py_BEGIN_CRITICAL_SECTION (self );
1440
1449
list_clear ((PyListObject * )self );
1450
+ Py_END_CRITICAL_SECTION ();
1441
1451
return 0 ;
1442
1452
}
1443
1453
@@ -3410,7 +3420,9 @@ list___init___impl(PyListObject *self, PyObject *iterable)
3410
3420
3411
3421
/* Empty previous contents */
3412
3422
if (self -> ob_item != NULL ) {
3423
+ Py_BEGIN_CRITICAL_SECTION (self );
3413
3424
list_clear (self );
3425
+ Py_END_CRITICAL_SECTION ();
3414
3426
}
3415
3427
if (iterable != NULL ) {
3416
3428
if (_list_extend (self , iterable ) < 0 ) {
@@ -3583,16 +3595,18 @@ adjust_slice_indexes(PyListObject *lst,
3583
3595
}
3584
3596
3585
3597
static int
3586
- list_ass_subscript (PyObject * _self , PyObject * item , PyObject * value )
3598
+ list_ass_subscript_lock_held (PyObject * _self , PyObject * item , PyObject * value )
3587
3599
{
3600
+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (_self );
3601
+
3588
3602
PyListObject * self = (PyListObject * )_self ;
3589
3603
if (_PyIndex_Check (item )) {
3590
3604
Py_ssize_t i = PyNumber_AsSsize_t (item , PyExc_IndexError );
3591
3605
if (i == -1 && PyErr_Occurred ())
3592
3606
return -1 ;
3593
3607
if (i < 0 )
3594
3608
i += PyList_GET_SIZE (self );
3595
- return list_ass_item (( PyObject * ) self , i , value );
3609
+ return list_ass_item_lock_held ( self , i , value );
3596
3610
}
3597
3611
else if (PySlice_Check (item )) {
3598
3612
Py_ssize_t start , stop , step ;
@@ -3612,7 +3626,7 @@ list_ass_subscript(PyObject* _self, PyObject* item, PyObject* value)
3612
3626
step );
3613
3627
3614
3628
if (step == 1 )
3615
- return list_ass_slice (self , start , stop , value );
3629
+ return list_ass_slice_lock_held (self , start , stop , value );
3616
3630
3617
3631
if (slicelength <= 0 )
3618
3632
return 0 ;
@@ -3678,10 +3692,8 @@ list_ass_subscript(PyObject* _self, PyObject* item, PyObject* value)
3678
3692
3679
3693
/* protect against a[::-1] = a */
3680
3694
if (self == (PyListObject * )value ) {
3681
- Py_BEGIN_CRITICAL_SECTION (value );
3682
- seq = list_slice_lock_held ((PyListObject * )value , 0 ,
3695
+ seq = list_slice_lock_held ((PyListObject * )value , 0 ,
3683
3696
Py_SIZE (value ));
3684
- Py_END_CRITICAL_SECTION ();
3685
3697
}
3686
3698
else {
3687
3699
seq = PySequence_Fast (value ,
@@ -3695,7 +3707,7 @@ list_ass_subscript(PyObject* _self, PyObject* item, PyObject* value)
3695
3707
step );
3696
3708
3697
3709
if (step == 1 ) {
3698
- int res = list_ass_slice (self , start , stop , seq );
3710
+ int res = list_ass_slice_lock_held (self , start , stop , seq );
3699
3711
Py_DECREF (seq );
3700
3712
return res ;
3701
3713
}
@@ -3751,6 +3763,24 @@ list_ass_subscript(PyObject* _self, PyObject* item, PyObject* value)
3751
3763
}
3752
3764
}
3753
3765
3766
+ static int
3767
+ list_ass_subscript (PyObject * self , PyObject * item , PyObject * value )
3768
+ {
3769
+ int res ;
3770
+ #ifdef Py_GIL_DISABLED
3771
+ if (PySlice_Check (item ) && value != NULL && PyList_CheckExact (value )) {
3772
+ Py_BEGIN_CRITICAL_SECTION2 (self , value );
3773
+ res = list_ass_subscript_lock_held (self , item , value );
3774
+ Py_END_CRITICAL_SECTION2 ();
3775
+ return res ;
3776
+ }
3777
+ #endif
3778
+ Py_BEGIN_CRITICAL_SECTION (self );
3779
+ res = list_ass_subscript_lock_held (self , item , value );
3780
+ Py_END_CRITICAL_SECTION ();
3781
+ return res ;
3782
+ }
3783
+
3754
3784
static PyMappingMethods list_as_mapping = {
3755
3785
list_length ,
3756
3786
list_subscript ,
0 commit comments