typo fix
[p5sagit/Devel-GlobalDestruction.git] / lib / Devel / GlobalDestruction.pm
CommitLineData
a91e8a78 1package Devel::GlobalDestruction;
2
3use strict;
4use warnings;
5
9e92a622 6our $VERSION = '0.11';
a91e8a78 7
aaccce0c 8use Sub::Exporter::Progressive -setup => {
53daa838 9 exports => [ qw(in_global_destruction) ],
10 groups => { default => [ -all ] },
a91e8a78 11};
12
6e3fd33e 13# we run 5.14+ - everything is in core
14#
eaac10b5 15if (defined ${^GLOBAL_PHASE}) {
62376bb4 16 eval 'sub in_global_destruction () { ${^GLOBAL_PHASE} eq q[DESTRUCT] }; 1'
17 or die $@;
3790e928 18}
6e3fd33e 19# try to load the xs version if it was compiled
20#
9aaf3646 21elsif (eval {
b1bee216 22 require Devel::GlobalDestruction::XS;
d4be4bd8 23 no warnings 'once';
b1bee216 24 *in_global_destruction = \&Devel::GlobalDestruction::XS::in_global_destruction;
53daa838 25 1;
9aaf3646 26}) {
53daa838 27 # the eval already installed everything, nothing to do
3790e928 28}
9aaf3646 29else {
23135b02 30 # internally, PL_main_start is nulled immediately before entering global destruction
5629eb97 31 # and we can use B to detect that. It will also be null before the main runloop starts,
32 # so we check install a CHECK if needed to detect that.
97415ced 33 require B;
5629eb97 34 my $started = !B::main_start()->isa(q[B::NULL]);
35 unless ($started) {
d4be4bd8 36 # work around 5.6 eval bug
37 eval '0 && $started; CHECK { $started = 1 }; 1'
5629eb97 38 or die $@;
39 }
d4be4bd8 40 eval '0 && $started; sub in_global_destruction () { $started && B::main_start()->isa(q[B::NULL]) }; 1'
97415ced 41 or die $@;
9aaf3646 42}
43
441; # keep require happy
45
46
47__END__
a91e8a78 48
49=head1 NAME
50
753fd2ff 51Devel::GlobalDestruction - Provides function returning the equivalent of
52C<${^GLOBAL_PHASE} eq 'DESTRUCT'> for older perls.
a91e8a78 53
54=head1 SYNOPSIS
55
f832e240 56 package Foo;
57 use Devel::GlobalDestruction;
a91e8a78 58
f832e240 59 use namespace::clean; # to avoid having an "in_global_destruction" method
a91e8a78 60
f832e240 61 sub DESTROY {
62 return if in_global_destruction;
a91e8a78 63
f832e240 64 do_something_a_little_tricky();
65 }
a91e8a78 66
67=head1 DESCRIPTION
68
69Perl's global destruction is a little tricky to deal with WRT finalizers
70because it's not ordered and objects can sometimes disappear.
71
72Writing defensive destructors is hard and annoying, and usually if global
ead5da2b 73destruction is happening you only need the destructors that free up non
a91e8a78 74process local resources to actually execute.
75
76For these constructors you can avoid the mess by simply bailing out if global
77destruction is in effect.
78
79=head1 EXPORTS
80
aaccce0c 81This module uses L<Sub::Exporter::Progressive> so the exports may be renamed,
82aliased, etc. if L<Sub::Exporter> is present.
a91e8a78 83
84=over 4
85
86=item in_global_destruction
87
761f3ee2 88Returns true if the interpreter is in global destruction. In perl 5.14+, this
6f93d768 89returns C<${^GLOBAL_PHASE} eq 'DESTRUCT'>, and on earlier perls, detects it using
90the value of C<PL_main_start> or C<PL_dirty>.
a91e8a78 91
92=back
93
ec94b9e1 94=head1 AUTHORS
a91e8a78 95
96Yuval Kogman E<lt>nothingmuch@woobling.orgE<gt>
97
ec94b9e1 98Florian Ragwitz E<lt>rafl@debian.orgE<gt>
99
aaa7f60f 100Jesse Luehrs E<lt>doy@tozt.netE<gt>
101
9aaf3646 102Peter Rabbitson E<lt>ribasushi@cpan.orgE<gt>
103
aaccce0c 104Arthur Axel 'fREW' Schmidt E<lt>frioux@gmail.comE<gt>
105
140a3884 106Elizabeth Mattijsen E<lt>liz@dijkmat.nlE<gt>
107
5ed10b49 108Greham Knop E<lt>haarg@haarg.orgE<gt>
109
a91e8a78 110=head1 COPYRIGHT
111
f832e240 112 Copyright (c) 2008 Yuval Kogman. All rights reserved
113 This program is free software; you can redistribute
114 it and/or modify it under the same terms as Perl itself.
a91e8a78 115
116=cut