From: Fred Drake Date: Tue, 3 Aug 2004 14:46:57 +0000 (+0000) Subject: Be more careful about maintaining the invariants; it was actually X-Git-Tag: v2.3.5c1~143 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=728b519b38302648886b4e69a584061a72088e05;p=thirdparty%2FPython%2Fcpython.git 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. --- diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index 575a928f7528..8ed3a5dad6bc 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -639,13 +639,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); @@ -695,8 +705,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; @@ -704,6 +724,8 @@ PyWeakref_NewProxy(PyObject *ob, PyObject *callback) insert_head(result, list); else insert_after(result, prev); + skip_insert: + ; } } return (PyObject *) result;