Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6d3265d

Browse files
committed
Be more careful about maintaining the invariants; it was actually
possible that the callback-less flavors of the ref or proxy could have been added during GC, so we don't want to replace them.
1 parent 43220ea commit 6d3265d

1 file changed

Lines changed: 25 additions & 3 deletions

File tree

Objects/weakrefobject.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -747,13 +747,23 @@ PyWeakref_NewRef(PyObject *ob, PyObject *callback)
747747
them. */
748748
result = new_weakref(ob, callback);
749749
if (result != NULL) {
750+
get_basic_refs(*list, &ref, &proxy);
750751
if (callback == NULL) {
751-
insert_head(result, list);
752+
if (ref == NULL)
753+
insert_head(result, list);
754+
else {
755+
/* Someone else added a ref without a callback
756+
during GC. Return that one instead of this one
757+
to avoid violating the invariants of the list
758+
of weakrefs for ob. */
759+
Py_DECREF(result);
760+
Py_INCREF(ref);
761+
result = ref;
762+
}
752763
}
753764
else {
754765
PyWeakReference *prev;
755766

756-
get_basic_refs(*list, &ref, &proxy);
757767
prev = (proxy == NULL) ? ref : proxy;
758768
if (prev == NULL)
759769
insert_head(result, list);
@@ -803,15 +813,27 @@ PyWeakref_NewProxy(PyObject *ob, PyObject *callback)
803813
else
804814
result->ob_type = &_PyWeakref_ProxyType;
805815
get_basic_refs(*list, &ref, &proxy);
806-
if (callback == NULL)
816+
if (callback == NULL) {
817+
if (proxy != NULL) {
818+
/* Someone else added a proxy without a callback
819+
during GC. Return that one instead of this one
820+
to avoid violating the invariants of the list
821+
of weakrefs for ob. */
822+
Py_DECREF(result);
823+
Py_INCREF(result = proxy);
824+
goto skip_insert;
825+
}
807826
prev = ref;
827+
}
808828
else
809829
prev = (proxy == NULL) ? ref : proxy;
810830

811831
if (prev == NULL)
812832
insert_head(result, list);
813833
else
814834
insert_after(result, prev);
835+
skip_insert:
836+
;
815837
}
816838
}
817839
return (PyObject *) result;

0 commit comments

Comments
 (0)