On Tue, Mar 14, 2017 at 05:20:38AM -0700, Nick Wellnhofer via RT wrote: > On Tue, 14 Mar 2017 01:46:17 -0700, davem wrote: > > Can you provide a short, self-contained perl program which demonstrates > > the bug, and which would be fixed by why you propose above; just so that > > we can be sure we're all discussing the same issue. > > I already did so here: > > https://rt.perl.org/Ticket/Display.html?id=32714#txn-1453380 Ah sorry, I completely failed to spot that when I looked. > I would expect $our1->DESTROY to be run before $our2->DESTROY because > $our1 holds a reference to $our2. But (at least with Perl 5.22.1), the > DESTROY method is first invoked on $our2. > I realize that this problem is harder than I initially thought. But I > think it could be solved by deferring freeing of package vars during > global destruction. So if a refcount drops to zero, DESTROY is invoked, > the object is not freed, but refcounts of other objects that are > referred to are decreased. In other words, you simulate freeing an > object just for refcount side effects. Then, in a second pass, DESTROY > is invoked on objects that still have a refcount (because of circular > references or refcount leaks). Note that the effect demonstrated by your code is not caused by global vars being freed - in fact during both calls to DESTROY, $our1 and $our2 exist and have a reference count >= 1. What is actually happening is that at that point during global destruction, perl is linearly scanning SV arenas looking for any RV which points to an object. Each such RV is undeffed (*not* freed), which may trigger a destructor call on the now not-so-referred-to object. So its a bit like your code having this in it: END { undef $our1; undef $our2 } except that the order is non-deterministic, so it could equally as well be END { undef $our2; undef $our1 } and note that its also unrelated to package vars: it's *any* RV that can be found (including anonymous ones) which gets zapped, in any order. So for example: our $x; $x->{l1}{l2}{l3}{l4} = 1; (where each hash is blessed) might have a destruction equivalent to any of these END { undef $x->{l1}{l2}; undef $x } END { undef $x } END { undef $x->{l1}{l2}{l3}; undef $x->{l1}; undef $x } ... etc ... Now having explained all that, I don't really understand your proposal above. Given that package vars *aren't* freed at that point during global destruction, could you update and clarify your proposal? -- In England there is a special word which means the last sunshine of the summer. That word is "spring".Thread Previous | Thread Next