@@ -3,9 +3,10 @@ from collections import defaultdict
3
3
cimport cython
4
4
from cpython.object cimport PyObject
5
5
from cpython.pyport cimport PY_SSIZE_T_MAX
6
+ from cpython.ref cimport Py_DECREF
6
7
from cpython.slice cimport PySlice_GetIndicesEx
7
8
from cpython.weakref cimport (
8
- PyWeakref_GetObject ,
9
+ PyWeakref_GetRef ,
9
10
PyWeakref_NewRef,
10
11
)
11
12
from cython cimport Py_ssize_t
@@ -908,11 +909,18 @@ cdef class BlockValuesRefs:
908
909
# if force=False. Clearing for every insertion causes slowdowns if
909
910
# all these objects stay alive, e.g. df.items() for wide DataFrames
910
911
# see GH#55245 and GH#55008
912
+ cdef PyObject* pobj
913
+ cdef bint status
914
+
911
915
if force or len (self .referenced_blocks) > self .clear_counter:
912
- self .referenced_blocks = [
913
- ref for ref in self .referenced_blocks
914
- if PyWeakref_GetObject(ref) != Py_None
915
- ]
916
+ new_referenced_blocks = []
917
+ for ref in self .referenced_blocks:
918
+ status = PyWeakref_GetRef(ref, & pobj)
919
+ if status == 1 :
920
+ new_referenced_blocks.append(ref)
921
+ Py_DECREF(< object > pobj)
922
+ self .referenced_blocks = new_referenced_blocks
923
+
916
924
nr_of_refs = len (self .referenced_blocks)
917
925
if nr_of_refs < self .clear_counter // 2 :
918
926
self .clear_counter = max (self .clear_counter // 2 , 500 )
@@ -927,8 +935,9 @@ cdef class BlockValuesRefs:
927
935
blk : Block
928
936
The block that the new references should point to.
929
937
"""
930
- self ._clear_dead_references()
931
- self .referenced_blocks.append(PyWeakref_NewRef(blk, None ))
938
+ with cython.critical_section(self ):
939
+ self ._clear_dead_references()
940
+ self .referenced_blocks.append(PyWeakref_NewRef(blk, None ))
932
941
933
942
def add_index_reference (self , index: object ) -> None:
934
943
"""Adds a new reference to our reference collection when creating an index.
@@ -938,8 +947,9 @@ cdef class BlockValuesRefs:
938
947
index : Index
939
948
The index that the new reference should point to.
940
949
"""
941
- self._clear_dead_references()
942
- self.referenced_blocks.append(PyWeakref_NewRef(index , None ))
950
+ with cython.critical_section(self ):
951
+ self ._clear_dead_references()
952
+ self .referenced_blocks.append(PyWeakref_NewRef(index, None ))
943
953
944
954
def has_reference (self ) -> bool:
945
955
"""Checks if block has foreign references.
@@ -951,6 +961,8 @@ cdef class BlockValuesRefs:
951
961
-------
952
962
bool
953
963
"""
954
- self._clear_dead_references(force = True )
955
- # Checking for more references than block pointing to itself
956
- return len(self.referenced_blocks ) > 1
964
+ with cython.critical_section(self ):
965
+ self ._clear_dead_references(force = True )
966
+ # Checking for more references than block pointing to itself
967
+ has_reference = len (self .referenced_blocks) > 1
968
+ return has_reference
0 commit comments