From 6d3265dab60c3ed12569a1ad1643d95ba8028cad Mon Sep 17 00:00:00 2001 From: Fred Drake Date: Tue, 3 Aug 2004 14:47:25 +0000 Subject: 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. --- Objects/weakrefobject.c | 28 +++++++++++++++++++++++++--- 1 file 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; -- cgit v0.12