summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFred Drake <fdrake@acm.org>2004-08-03 14:47:25 (GMT)
committerFred Drake <fdrake@acm.org>2004-08-03 14:47:25 (GMT)
commit6d3265dab60c3ed12569a1ad1643d95ba8028cad (patch)
tree2e516164c498b7ff885f5f607f4d516612375a20
parent43220ea26eaa2c840f04247c1339dc7eaf580a4f (diff)
downloadcpython-6d3265dab60c3ed12569a1ad1643d95ba8028cad.zip
cpython-6d3265dab60c3ed12569a1ad1643d95ba8028cad.tar.gz
cpython-6d3265dab60c3ed12569a1ad1643d95ba8028cad.tar.bz2
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.
-rw-r--r--Objects/weakrefobject.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c
index 54fe446..6da8192 100644
--- a/Objects/weakrefobject.c
+++ b/Objects/weakrefobject.c
@@ -747,13 +747,23 @@ PyWeakref_NewRef(PyObject *ob, PyObject *callback)
them. */
result = new_weakref(ob, callback);
if (result != NULL) {
+ get_basic_refs(*list, &ref, &proxy);
if (callback == NULL) {
- insert_head(result, list);
+ if (ref == NULL)
+ insert_head(result, list);
+ else {
+ /* Someone else added a ref without a callback
+ during GC. Return that one instead of this one
+ to avoid violating the invariants of the list
+ of weakrefs for ob. */
+ Py_DECREF(result);
+ Py_INCREF(ref);
+ result = ref;
+ }
}
else {
PyWeakReference *prev;
- get_basic_refs(*list, &ref, &proxy);
prev = (proxy == NULL) ? ref : proxy;
if (prev == NULL)
insert_head(result, list);
@@ -803,8 +813,18 @@ PyWeakref_NewProxy(PyObject *ob, PyObject *callback)
else
result->ob_type = &_PyWeakref_ProxyType;
get_basic_refs(*list, &ref, &proxy);
- if (callback == NULL)
+ if (callback == NULL) {
+ if (proxy != NULL) {
+ /* Someone else added a proxy without a callback
+ during GC. Return that one instead of this one
+ to avoid violating the invariants of the list
+ of weakrefs for ob. */
+ Py_DECREF(result);
+ Py_INCREF(result = proxy);
+ goto skip_insert;
+ }
prev = ref;
+ }
else
prev = (proxy == NULL) ? ref : proxy;
@@ -812,6 +832,8 @@ PyWeakref_NewProxy(PyObject *ob, PyObject *callback)
insert_head(result, list);
else
insert_after(result, prev);
+ skip_insert:
+ ;
}
}
return (PyObject *) result;