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

fdrake at users.sourceforge.net fdrake at users.sourceforge.net
Wed Feb 4 18:14:17 EST 2004


Update of /cvsroot/python/python/dist/src/Objects
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22056/Objects

Modified Files:
	weakrefobject.c 
Log Message:
Allocating a new weakref object can cause existing weakref objects for
the same object to be collected by the cyclic GC support if they are
only referenced by a cycle.  If the weakref being collected was one of
the weakrefs without callbacks, some local variables for the
constructor became invalid and have to be re-computed.

The test caused a segfault under a debug build without the fix applied.


Index: weakrefobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/weakrefobject.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -C2 -d -r1.15 -r1.16
*** weakrefobject.c	3 Feb 2004 19:52:56 -0000	1.15
--- weakrefobject.c	4 Feb 2004 23:14:14 -0000	1.16
***************
*** 631,636 ****
          result = ref;
      if (result != NULL)
!         Py_XINCREF(result);
      else {
          result = new_weakref(ob, callback);
          if (result != NULL) {
--- 631,641 ----
          result = ref;
      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) {
***************
*** 639,644 ****
              }
              else {
!                 PyWeakReference *prev = (proxy == NULL) ? ref : proxy;
  
                  if (prev == NULL)
                      insert_head(result, list);
--- 644,651 ----
              }
              else {
!                 PyWeakReference *prev;
  
+                 get_basic_refs(*list, &ref, &proxy);
+                 prev = (proxy == NULL) ? ref : proxy;
                  if (prev == NULL)
                      insert_head(result, list);
***************
*** 673,678 ****
          result = proxy;
      if (result != NULL)
!         Py_XINCREF(result);
      else {
          result = new_weakref(ob, callback);
          if (result != NULL) {
--- 680,690 ----
          result = proxy;
      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) {
***************
*** 683,686 ****
--- 695,699 ----
              else
                  result->ob_type = &_PyWeakref_ProxyType;
+             get_basic_refs(*list, &ref, &proxy);
              if (callback == NULL)
                  prev = ref;




More information about the Python-checkins mailing list