move schema state copy to _copy_state_from
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / GlobalDestruction.pm
CommitLineData
a4367b26 1# This is just a concept-test. If works as intended will ship in its own
2# right as Devel::GlobalDestruction::PP or perhaps even as part of rafls
3# D::GD itself
4
5package # hide from pause
6 DBIx::Class::GlobalDestruction;
7
8use strict;
9use warnings;
10
11use base 'Exporter';
12our @EXPORT = 'in_global_destruction';
13
14use DBIx::Class::Exception;
15
16if (defined ${^GLOBAL_PHASE}) {
17 eval 'sub in_global_destruction () { ${^GLOBAL_PHASE} eq q[DESTRUCT] }';
18}
19elsif (eval { require Devel::GlobalDestruction }) { # use the XS version if available
20 *in_global_destruction = \&Devel::GlobalDestruction::in_global_destruction;
21}
22else {
23 my ($in_global_destruction, $before_is_installed);
24
25 eval <<'PP_IGD';
26
27sub in_global_destruction () { $in_global_destruction }
28
29END {
30 # SpeedyCGI runs END blocks every cycle but keeps object instances
31 # hence we have to disable the globaldestroy hatch, and rely on the
32 # eval traps (which appears to work, but are risky done so late)
33 $in_global_destruction = 1 unless $CGI::SpeedyCGI::i_am_speedy;
34}
35
36# threads do not execute the global ENDs (it would be stupid). However
37# one can register a new END via simple string eval within a thread, and
38# achieve the same result. A logical place to do this would be CLONE, which
39# is claimed to run in the context of the new thread. However this does
40# not really seem to be the case - any END evaled in a CLONE is ignored :(
41# Hence blatantly hooking threads::create
42if ($INC{'threads.pm'}) {
43 require Class::Method::Modifiers;
44 Class::Method::Modifiers::install_modifier( threads => before => create => sub {
45 my $orig_target_cref = $_[1];
46 $_[1] = sub {
47 { local $@; eval 'END { $in_global_destruction = 1 }' }
48 $orig_target_cref->();
49 };
50 });
51 $before_is_installed = 1;
52}
53
54# just in case threads got loaded after DBIC (silly)
55sub CLONE {
56 DBIx::Class::Exception->throw("You must load the 'threads' module before @{[ __PACKAGE__ ]}")
57 unless $before_is_installed;
58}
59
60PP_IGD
61
62}
63
641;