From: Peter Rabbitson Date: Wed, 8 Aug 2012 20:00:42 +0000 (+0200) Subject: Fix pure-perl implementation incorrectly reporting GD during END phase (liz++) X-Git-Tag: Devel-GlobalDestruction-0.09~4 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=140a3884a09b85a2f4c988ffea726455e194066d;p=p5sagit%2FDevel-GlobalDestruction.git Fix pure-perl implementation incorrectly reporting GD during END phase (liz++) --- diff --git a/Changes b/Changes index a5eeb6a..61e40bb 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,5 @@ + * Fix pure-perl implementation incorrectly reporting GD during END phase + 0.08 Tue, 31 Jul 2012 * Switch to Sub::Exporter::Progressive diff --git a/lib/Devel/GlobalDestruction.pm b/lib/Devel/GlobalDestruction.pm index 99e3eec..dc4aa35 100644 --- a/lib/Devel/GlobalDestruction.pm +++ b/lib/Devel/GlobalDestruction.pm @@ -38,20 +38,23 @@ die("The pure-perl version of @{[__PACKAGE__]} can not function correctly under . "codepath.\n" ) if $CGI::SpeedyCGI::i_am_speedy; - my ($in_global_destruction, $before_is_installed); sub in_global_destruction () { $in_global_destruction } +# end_av trick suggested by liz++ +require B; +my $add_endblock = sub { + push @{ B::end_av()->object_2svref }, sub { $in_global_destruction = 1 }; +}; + # This block will fire towards the end of the program execution -# Since there is no way for us to generate an END which will execute *last* -# this is *NOT 100% INCOMPATIBLE* with XS/${^GLOBAL_PHASE}. We *may* end up -# with a true in_gloal_destruction() in the middle of another END block -# There are no practical cases where this matters. +# Use it to inject an END block which is guaranteed to run last +# (as long as something else doesn't inject yet another block in +# the same manner afterwards, at which point it hardly matters +# anyway) # -END { - $in_global_destruction = 1; -} +END { $add_endblock->() } # threads do not execute the global ENDs (it would be stupid). However # one can register a new END via simple string eval within a thread, and @@ -146,6 +149,8 @@ Peter Rabbitson Eribasushi@cpan.orgE Arthur Axel 'fREW' Schmidt Efrioux@gmail.comE +Elizabeth Mattijsen Eliz@dijkmat.nlE + =head1 COPYRIGHT Copyright (c) 2008 Yuval Kogman. All rights reserved diff --git a/t/01_basic.t b/t/01_basic.t index b93496a..c739a63 100644 --- a/t/01_basic.t +++ b/t/01_basic.t @@ -25,7 +25,7 @@ BEGIN { sub DESTROY { my $self = shift; $self->[0]->() } } -print "1..6\n"; +print "1..9\n"; our $had_error; @@ -58,6 +58,10 @@ sub ok ($$) { print "\n"; } +END { + ok( ! in_global_destruction(), 'Not yet in GD while in END block 2' ) +} + ok( eval "use Devel::GlobalDestruction; 1", "use Devel::GlobalDestruction" ); ok( defined &in_global_destruction, "exported" ); @@ -66,6 +70,13 @@ ok( defined prototype \&in_global_destruction, "defined prototype" ); ok( prototype \&in_global_destruction eq "", "empty prototype" ); -ok( !in_global_destruction(), "not in GD" ); +ok( ! in_global_destruction(), "Runtime is not GD" ); + +our $sg1 = Test::Scope::Guard->new(sub { ok( in_global_destruction(), "Final cleanup object destruction properly in GD" ) }); + +END { + ok( ! in_global_destruction(), 'Not yet in GD while in END block 1' ) +} -our $sg = Test::Scope::Guard->new(sub { ok( in_global_destruction(), "in GD" ) }); +our $sg2 = Test::Scope::Guard->new(sub { ok( ! in_global_destruction(), "Object destruction in END not considered GD" ) }); +END { undef $sg2 }