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;