[Python-Dev] RE: [Python-checkins] python/dist/src/Objects weakrefobject.c, 1.15, 1.16

Tim Peters tim.one at comcast.net
Fri Feb 6 01:11:53 EST 2004


> 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.




More information about the Python-Dev mailing list