[Zodb-checkins] CVS: Zope3/lib/python/Persistence - cPersistence.c:1.1.2.6

Jeremy Hylton jeremy@zope.com
Wed, 13 Feb 2002 19:23:58 -0500


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

Modified Files:
      Tag: Zope-3x-branch
	cPersistence.c 
Log Message:
Several fixes:

Handle deletion of _p_changed.

Don't change po_state in tp_setattro unless po_dm != NULL.  Basically
an object that doesn't yet have a data manager and an oid shouldn't
ever change its state.

Get rid of calls to PyType_Type.tp_XXX for dealloc, traverse, and
persist.  PyType_Type is the wrong class, and they probably aren't
needed anyway.



=== Zope3/lib/python/Persistence/cPersistence.c 1.1.2.5 => 1.1.2.6 ===
     if (self->po_state == UPTODATE && self->po_dm) {
 	PyObject **pdict = _PyObject_GetDictPtr((PyObject *)self);
+	/* XXX should be safe to actually delete the dictionary */
 	if (*pdict)
 	    PyDict_Clear(*pdict);
 	self->po_state = GHOST;
@@ -241,6 +242,7 @@
 #define CHANGED_NONE 0
 #define CHANGED_FALSE 1
 #define CHANGED_TRUE 2
+#define CHANGED_DELETE 3
 
 static int
 persist_set_state(PyPersistObject *self, PyObject *v)
@@ -256,18 +258,17 @@
 
     if (v == Py_None)
 	newstate = CHANGED_NONE;
+    else if (v == NULL)
+	newstate = CHANGED_DELETE;
     else if (PyObject_IsTrue(v)) 
 	newstate = CHANGED_TRUE;
-    else
+    else 
 	newstate = CHANGED_FALSE;
 
-    /* XXX What to do about del _p_changed? */
-
     /* XXX I think the cases below cover all the transitions of
        interest.  We should really extend the interface / documentation
        with a state transition diagram.
      */
-
     if (self->po_state == GHOST) {
 	if (newstate == CHANGED_TRUE || newstate == CHANGED_FALSE) {
 	    /* Turn a ghost into a real object. */
@@ -291,6 +292,12 @@
 	 */
 	if (self->po_state > 0) /* changed or sticky */
 	    self->po_state = UPTODATE;
+    } else if (newstate == CHANGED_DELETE) {
+	/* Force the object to UPTODATE state to guarantee that
+	   persist_deactivate() will turn it into a ghost.
+	*/
+	self->po_state = UPTODATE;
+	persist_deactivate(self);
     } else if (self->po_state == UPTODATE) {
 	/* The final case is for CHANGED_NONE, which is only
 	   meaningful when the object is already in the up-to-date state. 
@@ -450,8 +457,10 @@
 	    if (_PyPersist_Register(self) == NULL)
 		return -1;
 
-	self->po_state = CHANGED;
-	self->po_atime = time(NULL);
+	if (self->po_dm && self->po_oid) {
+	    self->po_state = CHANGED;
+	    self->po_atime = time(NULL);
+	}
     }
 
     /* XXX What will go wrong if someone assigns to an _p_ or _v_
@@ -469,7 +478,6 @@
     Py_XDECREF(self->po_dm);
     Py_XDECREF(self->po_oid);
     Py_XDECREF(self->po_serial);
-    PyType_Type.tp_dealloc((PyObject *)self);
 }
 
 static int
@@ -487,8 +495,7 @@
     VISIT(self->po_oid);
     VISIT(self->po_serial);
 #undef VISIT
-
-    return PyType_Type.tp_traverse((PyObject *)self, visit, arg);
+    return 0;
 }
 
 static int
@@ -500,7 +507,7 @@
     self->po_dm = NULL;
     self->po_oid = NULL;
     self->po_serial = NULL;
-    return PyType_Type.tp_clear((PyObject *)self);
+    return 0;
 }
 
 /* We link this module statically for convenience.  If compiled as a shared