File Coverage

lib/UR/Exit.pm
Criterion Covered Total %
statement 20 50 40.0
branch 6 30 20.0
condition 0 9 0.0
subroutine 6 8 75.0
pod 4 5 80.0
total 36 102 35.2


line stmt bran cond sub pod time code
1             package UR::Exit;
2              
3             =pod
4              
5             =head1 NAME
6              
7             UR::Exit - methods to allow clean application exits.
8              
9             =head1 SYNOPSIS
10              
11             UR::Exit->exit_handler(\&mysub);
12              
13             UR::Exit->clean_exit($value);
14              
15             =head1 DESCRIPTION
16              
17             This module provides the ability to perform certain operations before
18             an application exits.
19              
20             =cut
21              
22             # set up module
23             require 5.006_000;
24 266     266   947 use warnings;
  266         285  
  266         8999  
25 266     266   813 use strict;
  266         283  
  266         19892  
26             require UR;
27             our $VERSION = "0.46"; # UR $VERSION;;
28             our (@ISA, @EXPORT, @EXPORT_OK);
29              
30             require Exporter;
31             @ISA = qw(Exporter);
32             @EXPORT = qw();
33             @EXPORT_OK = qw();
34              
35 266     266   1062 use Carp;
  266         275  
  266         136368  
36              
37              
38             =pod
39              
40             =head1 METHODS
41              
42             These methods provide exit functionality.
43              
44             =over 4
45              
46             =item exit_handler
47              
48             UR::Exit->exit_handler(\&mysub);
49              
50             Specifies that a given subroutine be run when the application exits.
51             (Unimplimented!)
52              
53             =cut
54              
55             sub exit_handler
56             {
57 0     0 1 0 die "Unimplimented";
58             }
59              
60             =pod
61              
62             =item clean_exit
63              
64             UR::Exit->clean_exit($value);
65              
66             Exit the application, running all registered subroutines.
67             (Unimplimented! Just exits the application directly.)
68              
69             =cut
70              
71             sub clean_exit
72             {
73 0     0 1 0 my $class = shift;
74 0         0 my ($value) = @_;
75 0 0       0 $value = 0 unless defined($value);
76 0         0 exit($value);
77             }
78              
79             =pod
80              
81             =item death
82              
83             Catch any die or warn calls. This is a universal place to catch die
84             and warn if debugging.
85              
86             =cut
87              
88             sub death
89             {
90 11561 100   11561 1 682030 unless ($ENV{'UR_STACK_DUMP_ON_DIE'}) {
91 11560         61120 return;
92             }
93              
94             # workaround common error
95 1 50       7 if ($_[0] =~ /Can.*t upgrade that kind of scalar during global destruction/)
96             {
97 0         0 exit 1;
98             }
99              
100 1 50       3 if (defined $^S) {
101             # $^S is defined when perl is executing (as opposed to interpreting)
102 1 50       4 if ($^S) {
103             # $^S is true when its executing in an eval, false outside of one
104 1         6 return;
105             }
106             } else {
107             # interpreter is parsing a module or string eval
108             # check the call stack depth for up-stream evals
109             # fall back to perls default handler if there is one
110 0         0 my $call_stack_depth = 0;
111 0         0 for (1) {
112 0         0 my @details = caller($call_stack_depth);
113             #print Data::Dumper::Dumper(\@details);
114 0 0       0 last if scalar(@details) == 0;
115              
116 0 0       0 if ($details[1] =~ /\(eval .*\)/) {
    0          
117             #print "";
118 0         0 return;
119             }
120             elsif ($details[3] eq "(eval)") {
121             #print "";
122 0         0 return;
123             }
124 0         0 $call_stack_depth++;
125 0         0 redo;
126             }
127             }
128              
129 0 0 0     0 if
      0        
      0        
130             (
131             $_[0] =~ /\n$/
132             and UNIVERSAL::can("UR::Context::Process","is_initialized")
133             and defined(UR::Context::Process->is_initialized)
134             and (UR::Context::Process->is_initialized == 1)
135             )
136             {
137             # Do normal death if there is a newline at the end, and all other
138             # things are sane.
139 0         0 return;
140             }
141             else
142             {
143             # Dump the call stack in other cases.
144             # This is a developer error occurring while things are
145             # initializing.
146 0         0 local $Carp::CarpLevel = 1;
147 0         0 Carp::confess(@_);
148 0         0 return;
149             }
150             }
151              
152             =pod
153              
154             =item warning
155              
156             Give more informative warnings.
157              
158             =cut
159              
160             sub warning
161             {
162              
163 21 50   21 1 5863 unless ($ENV{'UR_STACK_DUMP_ON_WARN'}) {
164 21         1228 warn @_;
165 21         2924 return;
166             }
167              
168 0 0       0 return if $_[0] =~ /Attempt to free unreferenced scalar/;
169 0 0       0 return if $_[0] =~ /Use of uninitialized value in exit at/;
170 0 0       0 return if $_[0] =~ /Use of uninitialized value in subroutine entry at/;
171 0 0       0 return if $_[0] =~ /One or more DATA sections were not processed by Inline/;
172 0         0 UR::ModuleBase->warning_message(@_);
173 0 0       0 if ($_[0] =~ /Deep recursion on subroutine/)
174             {
175 0         0 print STDERR "Forced exit by UR::Exit on deep recursion.\n";
176 0         0 print STDERR Carp::longmess("Stack tail:");
177 0         0 exit 1;
178             }
179 0         0 return;
180             }
181              
182             #$SIG{__DIE__} = \&death unless ($SIG{__DIE__});
183             #$SIG{__WARN__} = \&warning unless ($SIG{__WARN__});
184              
185             sub enable_hooks_for_warn_and_die {
186 266     266 0 965 $SIG{__DIE__} = \&death;
187 266         685 $SIG{__WARN__} = \&warning;
188             }
189              
190             &enable_hooks_for_warn_and_die();
191              
192              
193             1;
194             __END__