diff options
author | ivan <ivan> | 2010-05-18 18:49:59 +0000 |
---|---|---|
committer | ivan <ivan> | 2010-05-18 18:49:59 +0000 |
commit | e70abd21bab68b23488f7ef1ee2e693a3b365691 (patch) | |
tree | 75986ffa9ba6ab4f961f9033468a1344e1653408 /rt/lib/RT/Util.pm | |
parent | b4b0c7e72d7eaee2fbfc7022022c9698323203dd (diff) |
import rt 3.8.8
Diffstat (limited to 'rt/lib/RT/Util.pm')
-rw-r--r-- | rt/lib/RT/Util.pm | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/rt/lib/RT/Util.pm b/rt/lib/RT/Util.pm index dd1572127..03d27a39e 100644 --- a/rt/lib/RT/Util.pm +++ b/rt/lib/RT/Util.pm @@ -54,6 +54,42 @@ use base 'Exporter'; our @EXPORT = qw/safe_run_child/; sub safe_run_child (&) { + my $our_pid = $$; + + # situation here is wierd, running external app + # involves fork+exec. At some point after fork, + # but before exec (or during) code can die in a + # child. Local is no help here as die throws + # error out of scope and locals are reset to old + # values. Instead we set values, eval code, check pid + # on failure and reset values only in our original + # process + my $dbh = $RT::Handle->dbh; + $dbh->{'InactiveDestroy'} = 1 if $dbh; + $RT::Handle->{'DisconnectHandleOnDestroy'} = 0; + + my @res; + my $want = wantarray; + eval { + unless ( defined $want ) { + _safe_run_child( @_ ); + } elsif ( $want ) { + @res = _safe_run_child( @_ ); + } else { + @res = ( scalar _safe_run_child( @_ ) ); + } + 1; + } or do { + if ( $our_pid == $$ ) { + $dbh->{'InactiveDestroy'} = 0 if $dbh; + $RT::Handle->{'DisconnectHandleOnDestroy'} = 1; + } + die $@; + }; + return $want? (@res) : $res[0]; +} + +sub _safe_run_child { local @ENV{ 'LANG', 'LC_ALL' } = ( 'C', 'C' ); return shift->() if $ENV{'MOD_PERL'} || $CGI::SpeedyCGI::i_am_speedy; |