]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Be more careful about maintaining the invariants; it was actually
authorFred Drake <fdrake@acm.org>
Tue, 3 Aug 2004 14:46:57 +0000 (14:46 +0000)
committerFred Drake <fdrake@acm.org>
Tue, 3 Aug 2004 14:46:57 +0000 (14:46 +0000)
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.

Objects/weakrefobject.c

index 575a928f7528f2c538e12210b264e3315e2af957..8ed3a5dad6bc61728df3ecb337f70e9e38e61d8c 100644 (file)
@@ -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;