]> granicus.if.org Git - python/commitdiff
Be more careful about maintaining the invariants; it was actually
authorFred Drake <fdrake@acm.org>
Tue, 3 Aug 2004 14:47:25 +0000 (14:47 +0000)
committerFred Drake <fdrake@acm.org>
Tue, 3 Aug 2004 14:47:25 +0000 (14:47 +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 54fe446e42fd8a853257ab7206dab599ae2a1902..6da8192da24e7df3a868e3cfe448bd4a3056ae59 100644 (file)
@@ -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;