[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