lucy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marvin Humphrey <mar...@rectangular.com>
Subject Re: [lucy-dev] Non-deterministic destruction in Perl 5.15
Date Fri, 09 Dec 2011 03:05:38 GMT
On Fri, Nov 11, 2011 at 02:51:26PM -0800, webmasters@ctosonline.org wrote:
> Perl previously did call DESTROY on objects during global destruction, and
> the order was non-determistic, but a few objects would escape the purge, in
> particular:
> 
> • blessed array elements (bless \$_[0])
> • blessed closure variables (bless my \$x; sub foo { $x ... })
> • any other unreferenced SVs (not referenced by RVs or GVs)
> 
> The VTables belong to the third category.

This is the key.

> Let’s look at the relevant code from the perl source:
> 
> > void
> > Perl_sv_clean_objs(pTHX)
> > {
> >    dVAR;
> >    GV *olddef, *olderr;
> >    PL_in_clean_objs = TRUE;
> 
> This line goes through all scalars that are references to objects and calls
> undef() on them:
> 
> >    visit(do_clean_objs, SVf_ROK, SVf_ROK);

> The next two function calls eliminate all blessed GV slots. I think the GV
> slots are nulled and the SVs in them have their reference count lowered, but
> I haven’t actually read the code.
> 
> >    /* Some barnacles may yet remain, clinging to typeglobs.
> >     * Run the non-IO destructors first: they may want to output
> >     * error messages, close files etc */
> >    visit(do_clean_named_objs, SVt_PVGV|SVpgv_GP, SVTYPEMASK|SVp_POK|SVpgv_GP);
> >    visit(do_clean_named_io_objs, SVt_PVGV|SVpgv_GP, SVTYPEMASK|SVp_POK|SVpgv_GP);
> 
> This is the bit added in 5.15. It looks for any objects remaining. Since
> they may be referenced by other objects (indirectly, through closures or
> array elements), whose destructors have not fired yet, they are not actually
> freed, but simply cursed; that is, they revert to non-object status
> (something you cannot do from Perl or XS, even though the core has the
> facility to do it).

OK, by now every Lucy object created by a direct user action should have gone
away, even if it was stuck in e.g. a Perl hash circular reference.

> >    /* And if there are some very tenacious barnacles clinging to arrays,
> >       closures, or what have you.... */
> >    visit(do_curse, SVs_OBJECT, SVs_OBJECT);

The only Lucy objects remaining at this point should be:

  * Static objects such as the VTables for all compiled classes.
  * Dynamically created VTables for Perl-space subclasses.
  * The VTable_registry (which is a Lucy::Object::LockFreeRegistry).
  * The keys for the VTable_registry, which are all CharBufs.

After examining the relevant destructors, I am satisfied that it doesn't
matter in which order any cached Perl objects associated with those Lucy
objects get reclaimed, so long as we sever the connection between the
Perl-space DESTROY method for Lucy::Object::VTable and VTable_destroy().

> So based on that it looks as though you simply need to remove the destructor
> on VTables, since they will be destroyed last. Or create a destructor that
> makes sure all other Lucy objects have been purged.
> 
> Now I hope I have you thoroughly confused. :-)

It took me a while to understand, but you have persuaded me that your solution
is the right one.

Thank you for sharing your valuable expertise on this subject.

Marvin Humphrey


Mime
View raw message