Mercurial > cpython-lru_cache-weakref
diff Objects/weakrefobject.c @ 32931:ec71ae3bc2dd 2.3
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.
| author | Fred Drake <fdrake@acm.org> |
|---|---|
| date | Tue, 03 Aug 2004 14:46:57 +0000 |
| parents | 3cc3cb79043f |
| children | b585bccfb250 |
line wrap: on
line diff
--- a/Objects/weakrefobject.c Tue Aug 03 13:00:52 2004 +0000 +++ b/Objects/weakrefobject.c Tue Aug 03 14:46:57 2004 +0000 @@ -639,13 +639,23 @@ 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 @@ 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 @@ insert_head(result, list); else insert_after(result, prev); + skip_insert: + ; } } return (PyObject *) result;
