add comment to explain use of main_start
[p5sagit/Devel-GlobalDestruction.git] / lib / Devel / GlobalDestruction.pm
CommitLineData
a91e8a78 1package Devel::GlobalDestruction;
2
3use strict;
4use warnings;
5
23d57d81 6our $VERSION = '0.09';
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 {
53daa838 22 require XSLoader;
23 XSLoader::load(__PACKAGE__, $VERSION);
24 1;
9aaf3646 25}) {
53daa838 26 # the eval already installed everything, nothing to do
3790e928 27}
9aaf3646 28else {
23135b02 29 # internally, PL_main_start is nulled immediately before entering global destruction
30 # and we can use B to detect that
97415ced 31 require B;
32 eval 'sub in_global_destruction () { B::main_start()->isa(q[B::NULL]) }; 1'
33 or die $@;
9aaf3646 34}
35
361; # keep require happy
37
38
39__END__
a91e8a78 40
41=head1 NAME
42
761f3ee2 43Devel::GlobalDestruction - Expose the flag which marks global
a91e8a78 44destruction.
45
46=head1 SYNOPSIS
47
f832e240 48 package Foo;
49 use Devel::GlobalDestruction;
a91e8a78 50
f832e240 51 use namespace::clean; # to avoid having an "in_global_destruction" method
a91e8a78 52
f832e240 53 sub DESTROY {
54 return if in_global_destruction;
a91e8a78 55
f832e240 56 do_something_a_little_tricky();
57 }
a91e8a78 58
59=head1 DESCRIPTION
60
61Perl's global destruction is a little tricky to deal with WRT finalizers
62because it's not ordered and objects can sometimes disappear.
63
64Writing defensive destructors is hard and annoying, and usually if global
65destruction is happenning you only need the destructors that free up non
66process local resources to actually execute.
67
68For these constructors you can avoid the mess by simply bailing out if global
69destruction is in effect.
70
71=head1 EXPORTS
72
aaccce0c 73This module uses L<Sub::Exporter::Progressive> so the exports may be renamed,
74aliased, etc. if L<Sub::Exporter> is present.
a91e8a78 75
76=over 4
77
78=item in_global_destruction
79
761f3ee2 80Returns true if the interpreter is in global destruction. In perl 5.14+, this
81returns C<${^GLOBAL_PHASE} eq 'DESTRUCT'>, and on earlier perls, it returns the
82current value of C<PL_dirty>.
a91e8a78 83
84=back
85
ec94b9e1 86=head1 AUTHORS
a91e8a78 87
88Yuval Kogman E<lt>nothingmuch@woobling.orgE<gt>
89
ec94b9e1 90Florian Ragwitz E<lt>rafl@debian.orgE<gt>
91
aaa7f60f 92Jesse Luehrs E<lt>doy@tozt.netE<gt>
93
9aaf3646 94Peter Rabbitson E<lt>ribasushi@cpan.orgE<gt>
95
aaccce0c 96Arthur Axel 'fREW' Schmidt E<lt>frioux@gmail.comE<gt>
97
140a3884 98Elizabeth Mattijsen E<lt>liz@dijkmat.nlE<gt>
99
a91e8a78 100=head1 COPYRIGHT
101
f832e240 102 Copyright (c) 2008 Yuval Kogman. All rights reserved
103 This program is free software; you can redistribute
104 it and/or modify it under the same terms as Perl itself.
a91e8a78 105
106=cut