[Python-checkins] python/dist/src/Objects weakrefobject.c, 1.13, 1.14

tim_one at users.sourceforge.net tim_one at users.sourceforge.net
Thu Nov 20 16:21:48 EST 2003


Update of /cvsroot/python/python/dist/src/Objects
In directory sc8-pr-cvs1:/tmp/cvs-serv30573/Objects

Modified Files:
	weakrefobject.c 
Log Message:
SF bug 839548:  Bug in type's GC handling causes segfaults.
Also SF patch 843455.

This is a critical bugfix.
I'll backport to 2.3 maint, but not beyond that.  The bugs this fixes
have been there since weakrefs were introduced.


Index: weakrefobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/weakrefobject.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -d -r1.13 -r1.14
*** weakrefobject.c	14 Jul 2003 21:46:23 -0000	1.13
--- weakrefobject.c	20 Nov 2003 21:21:46 -0000	1.14
***************
*** 54,58 ****
              *list = self->wr_next;
          self->wr_object = Py_None;
-         self->wr_callback = NULL;
          if (self->wr_prev != NULL)
              self->wr_prev->wr_next = self->wr_next;
--- 54,57 ----
***************
*** 61,68 ****
          self->wr_prev = NULL;
          self->wr_next = NULL;
!         Py_XDECREF(callback);
      }
  }
  
  
  static void
--- 60,94 ----
          self->wr_prev = NULL;
          self->wr_next = NULL;
!     }
!     if (callback != NULL) {
!         Py_DECREF(callback);
!         self->wr_callback = NULL;
      }
  }
  
+ /* Cyclic gc uses this to *just* clear the passed-in reference, leaving
+  * the callback intact and uncalled.  It must be possible to call self's
+  * tp_dealloc() after calling this, so self has to be left in a sane enough
+  * state for that to work.  We expect tp_dealloc to decref the callback
+  * then.  The reason for not letting clear_weakref() decref the callback
+  * right now is that if the callback goes away, that may in turn trigger
+  * another callback (if a weak reference to the callback exists) -- running
+  * arbitrary Python code in the middle of gc is a disaster.  The convolution
+  * here allows gc to delay triggering such callbacks until the world is in
+  * a sane state again.
+  */
+ void
+ _PyWeakref_ClearRef(PyWeakReference *self)
+ {
+     PyObject *callback;
+ 
+     assert(self != NULL);
+     assert(PyWeakref_Check(self));
+     /* Preserve and restore the callback around clear_weakref. */
+     callback = self->wr_callback;
+     self->wr_callback = NULL;
+     clear_weakref(self);
+     self->wr_callback = callback;
+ }
  
  static void
***************
*** 118,122 ****
      return self->hash;
  }
!     
  
  static PyObject *
--- 144,148 ----
      return self->hash;
  }
! 
  
  static PyObject *
***************
*** 325,329 ****
  WRAP_BINARY(proxy_ior, PyNumber_InPlaceOr)
  
! static int 
  proxy_nonzero(PyWeakReference *proxy)
  {
--- 351,355 ----
  WRAP_BINARY(proxy_ior, PyNumber_InPlaceOr)
  
! static int
  proxy_nonzero(PyWeakReference *proxy)
  {





More information about the Python-checkins mailing list