[Zope-Checkins] CVS: Zope/lib/python/ZODB - cPickleCache.c:1.52

Toby Dickenson tdickenson@geminidataloggers.com
Wed, 3 Apr 2002 12:20:36 -0500


Update of /cvs-repository/Zope/lib/python/ZODB
In directory cvs.zope.org:/tmp/cvs-serv30979

Modified Files:
	cPickleCache.c 
Log Message:
replaced placeholder; its needed to avoid dangling pointers

=== Zope/lib/python/ZODB/cPickleCache.c 1.51 => 1.52 ===
     cPersistentObject *object;
     int error;
+    CPersistentRing placeholder;
     CPersistentRing *here = self->ring_home.next;
 
 #ifdef MUCH_RING_CHECKING
@@ -278,13 +279,17 @@
         else if (object->state == cPersistent_UPTODATE_STATE) {
             /* deactivate it. This is the main memory saver. */
 
-            /* Save the next pointer of the object we're about to ghostify,
-             * so that we can follow the link after the ghosted object is
-             * removed from the ring (via ghostify()).
-             */
-
-            /* FIXME: This needs to be changed back to a placeholder */
-            CPersistentRing *next = here->next;
+            /* Add a placeholder; a dummy node in the ring. We need to
+            do this to mark our position in the ring. All the other nodes
+            come from persistent objects, and they are all liable
+            to be deallocated before "obj._p_changed = None" returns
+            to this function. This operation is only safe when the
+            ring lock is held (and it is) */
+
+            placeholder.next = here->next;
+            placeholder.prev = here;
+            here->next->prev = &placeholder;
+            here->next = &placeholder;
 
             ENGINE_NOISE("G");
 
@@ -292,7 +297,12 @@
             error = PyObject_SetAttr((PyObject *)object, py__p_changed, 
 				     Py_None);
 
-            here = next;
+
+            /* unlink the placeholder */
+            placeholder.next->prev = placeholder.prev;
+            placeholder.prev->next = placeholder.next;
+
+            here = placeholder.next;
 
             if (error)
                 return -1; /* problem */