diff options
author | Fred Drake <fdrake@acm.org> | 2004-08-03 14:47:25 (GMT) |
---|---|---|
committer | Fred Drake <fdrake@acm.org> | 2004-08-03 14:47:25 (GMT) |
commit | 6d3265dab60c3ed12569a1ad1643d95ba8028cad (patch) | |
tree | 2e516164c498b7ff885f5f607f4d516612375a20 | |
parent | 43220ea26eaa2c840f04247c1339dc7eaf580a4f (diff) | |
download | cpython-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.c | 28 |
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; |