[Zope-Checkins] CVS: ZODB3/Persistence - cPersistence.c:1.72.8.13

Jeremy Hylton jeremy@zope.com
Thu, 3 Jul 2003 18:22:09 -0400


Update of /cvs-repository/ZODB3/Persistence
In directory cvs.zope.org:/tmp/cvs-serv30338/Persistence

Modified Files:
      Tag: zodb33-devel-branch
	cPersistence.c 
Log Message:
Add GC support and free the instance dict on ghostification.


=== ZODB3/Persistence/cPersistence.c 1.72.8.12 => 1.72.8.13 ===
--- ZODB3/Persistence/cPersistence.c:1.72.8.12	Thu Jul  3 17:40:11 2003
+++ ZODB3/Persistence/cPersistence.c	Thu Jul  3 18:22:05 2003
@@ -133,6 +133,7 @@
 static void
 ghostify(cPersistentObject *self)
 {
+    PyObject **dictptr;
     /* are we already a ghost? */
     if (self->state == cPersistent_GHOST_STATE)
         return;
@@ -158,6 +159,11 @@
     self->ring.prev = NULL;
     self->ring.next = NULL;
     self->state = cPersistent_GHOST_STATE;
+    dictptr = _PyObject_GetDictPtr((PyObject *)self);
+    if (dictptr && *dictptr) {
+	Py_DECREF(*dictptr);
+	*dictptr = NULL;
+    }
 
     /* We remove the reference to the just ghosted object that the ring
      * holds.  Note that the dictionary of oids->objects has an uncounted
@@ -177,6 +183,7 @@
 	/* XXX This function shouldn't be able to fail? If not, maybe
 	   it shouldn't set an exception either.
 	*/
+	/* Remove the object from the cache and DECREF self->cache */
 	if (cPersistenceCAPI->percachedel(self->cache, self->oid) < 0)
 	    PyErr_Clear(); /* I don't think this should ever happen */
     }
@@ -373,13 +380,41 @@
   {NULL,		NULL}		/* sentinel */
 };
 
-/* ---------- */
-
 static void
 Per_dealloc(cPersistentObject *self)
 {
-  deallocated(self);
-  self->ob_type->tp_free(self);
+    deallocated(self);
+    self->ob_type->tp_free(self);
+}
+
+static int
+Per_clear(cPersistentObject *self)
+{
+    deallocated(self);
+    self->jar = NULL;
+    self->oid = NULL;
+    self->cache = NULL;
+    return 0;
+}
+
+static int
+Per_traverse(cPersistentObject *self, visitproc visit, void *arg)
+{
+    int err;
+
+#define VISIT(SLOT) \
+    if (SLOT) { \
+	err = visit((PyObject *)(SLOT), arg); \
+	if (err) \
+		     return err; \
+    }
+
+    VISIT(self->jar);
+    VISIT(self->oid);
+    VISIT(self->cache);
+
+#undef VISIT
+    return 0;
 }
 
 /* convert_name() returns a new reference to a string name
@@ -708,10 +743,6 @@
    for documentation -- the macro ignores it.
 */
 #define DEFERRED_ADDRESS(ADDR) 0
-
-/* A reminder that these need to be implemented. */
-#define Per_traverse 0
-#define Per_clear 0
 
 static PyTypeObject Pertype = {
     PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyPersist_MetaType))