File tree Expand file tree Collapse file tree 2 files changed +16
-2
lines changed
Expand file tree Collapse file tree 2 files changed +16
-2
lines changed Original file line number Diff line number Diff line change @@ -99,7 +99,7 @@ impl RefCount {
9999 #[ inline]
100100 pub fn inc ( & self ) {
101101 let val = State :: from_raw ( self . state . fetch_add ( COUNT , Ordering :: SeqCst ) ) ;
102- if val. destructed ( ) {
102+ if val. destructed ( ) || ( val . strong ( ) as usize ) > STRONG - 1 {
103103 refcount_overflow ( ) ;
104104 }
105105 if val. strong ( ) == 0 {
Original file line number Diff line number Diff line change @@ -127,7 +127,9 @@ mod trashcan {
127127 #[ inline]
128128 pub ( super ) unsafe fn end ( ) {
129129 let depth = DEALLOC_DEPTH . with ( |d| {
130- let depth = d. get ( ) - 1 ;
130+ let depth = d. get ( ) ;
131+ debug_assert ! ( depth > 0 , "trashcan::end called without matching begin" ) ;
132+ let depth = depth - 1 ;
131133 d. set ( depth) ;
132134 depth
133135 } ) ;
@@ -434,6 +436,18 @@ impl WeakRefList {
434436 // Re-acquire lock for linked list insertion
435437 let _lock = weakref_lock:: lock ( obj as * const PyObject as usize ) ;
436438
439+ // Re-check: another thread may have inserted a generic ref while we
440+ // were allocating outside the lock. If so, reuse it and drop ours.
441+ if is_generic {
442+ let generic_ptr = self . generic . load ( Ordering :: Relaxed ) ;
443+ if !generic_ptr. is_null ( ) {
444+ let generic = unsafe { & * generic_ptr } ;
445+ if generic. 0 . ref_count . safe_inc ( ) {
446+ return unsafe { PyRef :: from_raw ( generic_ptr) } ;
447+ }
448+ }
449+ }
450+
437451 // Insert into linked list under stripe lock
438452 let node_ptr = NonNull :: from ( & * weak) ;
439453 unsafe {
You can’t perform that action at this time.
0 commit comments