[Rt-commit] rt branch, 4.0/dbh-disconnect-after-safe-run-child, updated. rt-4.0.3-48-gfa65b29
Alex Vandiver
alexmv at bestpractical.com
Wed Dec 14 14:34:25 EST 2011
The branch, 4.0/dbh-disconnect-after-safe-run-child has been updated
via fa65b29c46def6414a7b54a250469cddac19b6e0 (commit)
from 224781e7720e0569801fc0ddb211f57b3671e7c3 (commit)
Summary of changes:
lib/RT/Util.pm | 3 ++-
t/api/safe-run-child-util.t | 39 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 40 insertions(+), 2 deletions(-)
- Log -----------------------------------------------------------------
commit fa65b29c46def6414a7b54a250469cddac19b6e0
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Wed Dec 14 14:06:30 2011 -0500
Cope with children of safe_run_child that don't immediately exit
By making the read from the pipe non-blocking, it deals gracefully with
the case where the child is still running, and thus has left the pipe
open. This will eventually cause a zombie child, as it will not be
reaped, but does allow for safe_run_child to continue if its process
chooses to not wait() or waitpid() and the child survives.
diff --git a/lib/RT/Util.pm b/lib/RT/Util.pm
index 32932a0..4da8b43 100644
--- a/lib/RT/Util.pm
+++ b/lib/RT/Util.pm
@@ -100,7 +100,8 @@ sub safe_run_child (&) {
};
close($writer);
- my ($response) = <$reader>;
+ $reader->blocking(0);
+ my ($response) = $reader->getline;
warn $response if $response;
$dbh->{'InactiveDestroy'} = 0 if $dbh;
diff --git a/t/api/safe-run-child-util.t b/t/api/safe-run-child-util.t
index f5d78b3..e94f14e 100644
--- a/t/api/safe-run-child-util.t
+++ b/t/api/safe-run-child-util.t
@@ -3,7 +3,7 @@
use strict;
use warnings;
-use RT::Test tests => 27;
+use RT::Test tests => 35;
use Test::Warn;
use RT::Util qw(safe_run_child);
@@ -136,6 +136,43 @@ END
is_handle_ok();
}
+# fork+parent that doesn't wait()
+{
+ require Time::HiRes;
+ my $start = Time::HiRes::time();
+ my $pid;
+ my $res = safe_run_child {
+ if ($pid = fork) { return 'parent' }
+
+ open my $fh, '>', RT::Test->temp_directory .'/first';
+ print $fh "child";
+ close $fh;
+
+ sleep 5;
+
+ open $fh, '>', RT::Test->temp_directory .'/second';
+ print $fh "child";
+ close $fh;
+
+ exit 0;
+ };
+ ok( Time::HiRes::time() - $start < 5, "Didn't wait until child finished" );
+ is $res, 'parent', "correct return value";
+ is( RT::Test->file_content([RT::Test->temp_directory, 'first'], unlink => 1 ),
+ 'child',
+ 'correct file content',
+ );
+ ok( not(-f RT::Test->temp_directory.'/second'), "Second file does not exist yet");
+ is_handle_ok();
+
+ ok(waitpid($pid,0), "Waited until child finished to reap");
+ is( RT::Test->file_content([RT::Test->temp_directory, 'second'], unlink => 1 ),
+ 'child',
+ 'correct file content',
+ );
+ is_handle_ok();
+}
+
sub is_handle_ok {
local $Test::Builder::Level = $Test::Builder::Level + 1;
my $test = $RT::Handle->dbh->selectall_arrayref(
-----------------------------------------------------------------------
More information about the Rt-commit
mailing list