RE: [Python-checkins] python/dist/src/Objects weakrefobject.c, 1.15, 1.16
Modified Files: weakrefobject.c Log Message:
...
Index: weakrefobject.c ===================================================================
... and it leaves part of PyWeakref_NewRef() looking like: if (result != NULL) Py_INCREF(result); else { /* Note: new_weakref() can trigger cyclic GC, so the weakref list on ob can be mutated. This means that the ref and proxy pointers we got back earlier may have been collected, so we need to compute these values again before we use them. */ result = new_weakref(ob, callback); if (result != NULL) { if (callback == NULL) { insert_head(result, list); } else { When we call new_weakref(), callback may or may not be NULL. Assume it's NULL. Then we don't get into this code unless the first call to get_basic_refs() said there was not already a canonical weakref-without-callback weakref for ob. Cyclic gc can execute arbitrary Python code, if __del__ methods or callbacks get executed as a result of refcounts falling to 0 during cyclic gc. That code could in turn *create* a canonical weakref-without-callback weakref for ob, even while we're in the middle of creating our own. Suppose it does, and result isn't NULL. Then it looks like insert_head(result, list) is going to insert a second weakref-without-callback weakref for ob. Wouldn't that violate an excruciating global invariant? For example, PyObject_ClearWeakRefs() assumes that callback isn't NULL when it gets beyond the first two weakref objects in a weakref list, and get_basic_refs() assumes it never has to look at more than the first two weakref objects in a weakref list to determine whether a canonical weakref-proxy object for ob exists.
participants (1)
-
Tim Peters