@@ -502,7 +502,16 @@ list_item(PyObject *aa, Py_ssize_t i)
502
502
PyErr_SetObject (PyExc_IndexError , & _Py_STR (list_err ));
503
503
return NULL ;
504
504
}
505
- return Py_NewRef (a -> ob_item [i ]);
505
+ PyObject * item ;
506
+ Py_BEGIN_CRITICAL_SECTION (a );
507
+ #ifdef Py_GIL_DISABLED
508
+ if (!_Py_IsOwnedByCurrentThread ((PyObject * )a ) && !_PyObject_GC_IS_SHARED (a )) {
509
+ _PyObject_GC_SET_SHARED (a );
510
+ }
511
+ #endif
512
+ item = Py_NewRef (a -> ob_item [i ]);
513
+ Py_END_CRITICAL_SECTION ();
514
+ return item ;
506
515
}
507
516
508
517
static PyObject *
@@ -658,7 +667,7 @@ list_repeat(PyObject *aa, Py_ssize_t n)
658
667
}
659
668
660
669
static void
661
- list_clear (PyListObject * a )
670
+ list_clear_impl (PyListObject * a , bool is_resize )
662
671
{
663
672
PyObject * * items = a -> ob_item ;
664
673
if (items == NULL ) {
@@ -674,17 +683,31 @@ list_clear(PyListObject *a)
674
683
while (-- i >= 0 ) {
675
684
Py_XDECREF (items [i ]);
676
685
}
677
- // TODO: Use QSBR technique, if the list is shared between threads,
678
- PyMem_Free (items );
679
-
686
+ #ifdef Py_GIL_DISABLED
687
+ bool use_qsbr = is_resize && _PyObject_GC_IS_SHARED (a );
688
+ #else
689
+ bool use_qsbr = false;
690
+ #endif
691
+ if (use_qsbr ) {
692
+ _PyMem_FreeDelayed (items );
693
+ }
694
+ else {
695
+ PyMem_Free (items );
696
+ }
680
697
// Note that there is no guarantee that the list is actually empty
681
698
// at this point, because XDECREF may have populated it indirectly again!
682
699
}
683
700
701
+ static void
702
+ list_clear (PyListObject * a )
703
+ {
704
+ list_clear_impl (a , true);
705
+ }
706
+
684
707
static int
685
708
list_clear_slot (PyObject * self )
686
709
{
687
- list_clear ((PyListObject * )self );
710
+ list_clear_impl ((PyListObject * )self , false );
688
711
return 0 ;
689
712
}
690
713
0 commit comments