lucy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marvin Humphrey <>
Subject Re: [lucy-dev] Perl’s global destruction
Date Mon, 20 Jun 2011 03:47:02 GMT
On Sun, Jun 19, 2011 at 06:01:33PM -0700, wrote:
> > First, change VTable's destructor to a no-op, so that it no longer throws an
> > error.  As soon as we do this, tests will start passing again.
> > 
> > Second, perhaps we should change lucy_Memory_wrapped_free() to a no-op once we
> > enter the global destruction phase.  That way, even when SegWriter gets
> > reclaimed first, there's still a real object at indexer->seg_writer instead of
> > a dangling pointer.
> Or you could use END blocks, as you suggested for KinoSearch::Simple (at
> least two renamings ago), and for which I wrote a patch that you applied.
> The same technique could be applied to other classes with a has-a
> relationship.

Hmm, I think Lucy::Simple is a special case.  It's one of only two classes
where we're counting on the destructor to do something important -- run
Indexer's commit() method, flushing buffered adds to disk.  

It's best practice to avoid relying on object clean up for crucial behaviors
-- and this change to Perl illustrates exactly why.  Under tracing garbage
collection, it's even more important, because finalizers (as opposed to
destructors) always fire non-deterministically.

To my mind, any object that has made it through to global destruction time
because of leaked reference counts is hosed.  It's not worth trying to impose
a deterministic scheme at that point -- too many opportunities for error.
(What order will the END blocks run in?)

The other class with an important destructor is OutStream, which flushes
buffered writes by calling FH_Write(self->file_handle).  We should probably
remove that behavior.  It's about to become dangerous -- if the FileHandle's
destructor fires before the destructor of the OutStream that wraps it, the
OutStream will be attempting to write to a closed stream.

> In any case, this second fix that you are suggesting is unrelated to the
> Perl change I mentioned above. (Prior to that change, the VTable object
> would be freed, but without its destructor called.)

Think of each VTable has having two parts: a Clownfish object, and a Perl
object.  They point at each other in a circular reference.  However, the
Clownfish object delegates reference counting to the Perl object, so the pair
of objects share a single unified refcount.  When that refcount falls to 0,
the Perl destructor gets called.

For current stable Perl behavior, during global destruction the Perl SV* gets
freed, but since the destructor is never called, the Clownfish object leaks
and is left behind.  It's freed when the OS cleans up the process.

Marvin Humphrey

View raw message