[Zodb-checkins] CVS: Zope3/lib/python/Persistence/BTrees - BTreeTemplate.c:1.1.2.24 BucketTemplate.c:1.1.2.23

Jeremy Hylton jeremy@zope.com
Fri, 7 Jun 2002 09:59:26 -0400


Update of /cvs-repository/Zope3/lib/python/Persistence/BTrees
In directory cvs.zope.org:/tmp/cvs-serv3702

Modified Files:
      Tag: Zope-3x-branch
	BTreeTemplate.c BucketTemplate.c 
Log Message:
Fix dealloc code to free the object last rather than in the middle.

The previous checkin changed the order of the dealloc calls, so that
the base persistent tp_dealloc was called before _bucket_clear().
This was necessary so that po_dm etc. are cleared before calling
_bucket_clear(), which prevents the persistence machinery from
registering a dying object with the transaction manager.

*BUT* the base tp_dealloc also calls PyObject_GC_Del() on the object
-- which frees the memory.  So it isn't safe to call _bucket_clear()
after base tp_dealloc().

The temporary solution is to copy the code from base tp_dealloc into
the Bucket and BTree dealloc and arrange for everything to happen in
the right order there.  The fix is temporary because it forces all
subtypes of persistent to know intimate details about how to dealloc
the object that should be contained in the base type.  Need to define
macros or extend the C API to do this right.



=== Zope3/lib/python/Persistence/BTrees/BTreeTemplate.c 1.1.2.23 => 1.1.2.24 ===
     if (self->po_weaklist != NULL)
         PyObject_ClearWeakRefs((PyObject *)self);
-    PyPersist_BASE_TYPE->tp_dealloc((PyObject *)self);
+    Py_XDECREF(self->po_dm);
+    Py_XDECREF(self->po_oid);
+    Py_XDECREF(self->po_serial);
     if (self->po_state != GHOST)
 	_BTree_clear(self);
+    PyObject_GC_Del(self);
 }
 
 static int


=== Zope3/lib/python/Persistence/BTrees/BucketTemplate.c 1.1.2.22 => 1.1.2.23 ===
     if (self->po_weaklist != NULL)
         PyObject_ClearWeakRefs((PyObject *)self);
-    PyPersist_BASE_TYPE->tp_dealloc((PyObject *)self);
-    if (self->po_state != GHOST)
+    Py_XDECREF(self->po_dm);
+    Py_XDECREF(self->po_oid);
+    Py_XDECREF(self->po_serial);
+    if (self->po_state != GHOST) 
 	_bucket_clear(self);
+    PyObject_GC_Del(self);
 }
 
 static int