[Zope3-checkins] CVS: ZODB3/ZODB - cPickleCache.c:1.85.6.4

Chris McDonough chrism at plope.com
Tue May 18 14:53:33 EDT 2004


This suspense is killing me! ;-)

On Tue, 2004-05-18 at 14:31, Tim Peters wrote:
> Update of /cvs-repository/ZODB3/ZODB
> In directory cvs.zope.org:/tmp/cvs-serv6721/ZODB
> 
> Modified Files:
>       Tag: Zope-2_7-branch
> 	cPickleCache.c 
> Log Message:
> scan_gc_items():  so-far semantically neutral code and comment cleanups.
> Gave it a single exit point because it will soon need one <wink>.  Added
> simple insert_after() and unlink_from_ring() utility functions (which
> will also simplify what's coming next).
> 
> 
> === ZODB3/ZODB/cPickleCache.c 1.85.6.3 => 1.85.6.4 ===
> --- ZODB3/ZODB/cPickleCache.c:1.85.6.3	Tue May 18 11:54:44 2004
> +++ ZODB3/ZODB/cPickleCache.c	Tue May 18 14:31:24 2004
> @@ -146,6 +146,27 @@
>  
>  } ccobject;
>  
> +/* Insert self into the ring, following after. */
> +static void
> +insert_after(CPersistentRing *self, CPersistentRing *after)
> +{
> +    assert(self != NULL);
> +    assert(after != NULL);
> +    self->prev = after;
> +    self->next = after->next;
> +    after->next->prev = self;
> +    after->next = self;
> +}
> +
> +/* Remove self from the ring. */
> +static void
> +unlink_from_ring(CPersistentRing *self)
> +{
> +    assert(self != NULL);
> +    self->prev->next = self->next;
> +    self->next->prev = self->prev;
> +}
> +
>  static int cc_ass_sub(ccobject *self, PyObject *key, PyObject *v);
>  
>  /* ---------------------------------------------------------------- */
> @@ -159,20 +180,18 @@
>      /* This function must only be called with the ring lock held,
>         because it places a non-object placeholder in the ring.
>      */
> -
>      cPersistentObject *object;
>      int error;
>      CPersistentRing placeholder;
>      CPersistentRing *here = self->ring_home.next;
> +    int result = -1;   /* guilty until proved innocent */
>  
>      /* Scan through the ring until we either find the ring_home (i.e. start
> -     * of the ring, or we've ghosted enough objects to reach the target
> +     * of the ring), or we've ghosted enough objects to reach the target
>       * size.
>       */
> -    while (1) {
> -	/* back to the home position. stop looking */
> -        if (here == &self->ring_home)
> -            return 0;
> +    while (here != &self->ring_home && self->non_ghost_count > target) {
> +	assert(self->ring_lock);
>  
>          /* At this point we know that the ring only contains nodes
>  	   from persistent objects, plus our own home node. We know
> @@ -180,51 +199,40 @@
>  	   the current ring node is a persistent object now we know it
>  	   is not the home */
>          object = OBJECT_FROM_RING(self, here, "scan_gc_items");
> -        if (!object)
> -	    return -1;
>  
> -	/* we are small enough */
> -        if (self->non_ghost_count <= target)
> -            return 0;
> -        else if (object->state == cPersistent_UPTODATE_STATE) {
> +        if (object->state == cPersistent_UPTODATE_STATE) {
>              /* deactivate it. This is the main memory saver. */
>  
> -            /* Add a placeholder; a dummy node in the ring.  We need
> +            /* Add a placeholder;  a dummy node in the ring.  We need
>  	       to do this to mark our position in the ring.  It is
>  	       possible that the PyObject_SetAttr() call below will
> -	       invoke an __setattr__() hook in Python.  If it does,
> -	       another thread might run; if that thread accesses a
> -	       persistent object and moves it to the head of the ring,
> -	       it might cause the gc scan to start working from the
> -	       head of the list.
> +	       invoke a __setattr__() hook in Python.  Also possible
> +	       that deactivation will lead to a __del__ method call.
> +	       So another thread might run, and mutate the ring as a side
> +	       effect of object accesses.  There's no predicting then where
> +	       in the ring here->next will point after that.  The
> +	       placeholder won't move as a side effect of calling Python
> +	       code.
>  	    */
> -
> -            placeholder.next = here->next;
> -            placeholder.prev = here;
> -            here->next->prev = &placeholder;
> -            here->next = &placeholder;
> -
> +            insert_after(&placeholder, here);
>              ENGINE_NOISE("G");
>  
> -            /* In Python, "obj._p_changed = None" spells, ghostify */
> +            /* In Python, "obj._p_changed = None" spells ghostify */
>              error = PyObject_SetAttr((PyObject *)object, py__p_changed,
>  				     Py_None);
> -
> -
> -            /* unlink the placeholder */
> -            placeholder.next->prev = placeholder.prev;
> -            placeholder.prev->next = placeholder.next;
> -
>              here = placeholder.next;
> -
> -            if (error)
> -                return -1; /* problem */
> +            unlink_from_ring(&placeholder);
> +            if (error < 0)
> +                goto Done;
>          }
>          else {
>              ENGINE_NOISE(".");
>              here = here->next;
>          }
>      }
> +    result = 0;
> + Done:
> +    return result;
>  }
>  
>  static PyObject *
> @@ -241,7 +249,7 @@
>  
>      ENGINE_NOISE("<");
>      self->ring_lock = 1;
> -    if (scan_gc_items(self, target_size)) {
> +    if (scan_gc_items(self, target_size) < 0) {
>          self->ring_lock = 0;
>          return NULL;
>      }
> 
> 
> _______________________________________________
> Zope3-Checkins mailing list
> Zope3-Checkins at zope.org
> http://mail.zope.org/mailman/listinfo/zope3-checkins




More information about the Zope3-Checkins mailing list