Permalink
Browse files

Added detach, updated docs, new version

  • Loading branch information...
1 parent 06df6c9 commit e1ff7dbea29f4e35cb6effa7047f0ab6409268af @exodist committed Jul 23, 2010
Showing with 65 additions and 10 deletions.
  1. +31 −6 lib/Child.pm
  2. +34 −4 t/Child.t
View
@@ -3,11 +3,11 @@ use strict;
use warnings;
use Carp;
-our $VERSION = "0.005";
+our $VERSION = "0.006";
our %META;
our @CHILDREN;
-for my $reader ( qw/pid ipc exit code parent/ ) {
+for my $reader ( qw/pid ipc exit code parent detached/ ) {
my $prop = "_$reader";
my $psub = sub {
@@ -82,6 +82,7 @@ sub start {
@CHILDREN = ();
$self->_parent( $parent );
$self->_init_ipc if $self->ipc;
+ local $SIG{USR1} = sub { $self->detach };
my $code = $self->code;
$self->$code();
exit;
@@ -190,8 +191,7 @@ sub autoflush {
my $write = $self->_write_handle;
my $selected = select( $write );
- no warnings 'uninitialized';
- $| = ($value || undef) if @_;
+ $| = $value if @_;
my $out = $|;
select( $selected );
@@ -204,7 +204,6 @@ sub flush {
my $orig = $self->autoflush();
$self->autoflush(1);
my $write = $self->_write_handle;
-# print $write "";
$self->autoflush($orig);
}
@@ -225,6 +224,26 @@ sub write {
print $handle @_;
}
+sub detach {
+ my $self = shift;
+ return $self->_detach_as_parent if $self->pid;
+ return $self->_detach_as_child if $self->parent;
+ croak( "Nothing to detach" )
+}
+
+sub _detach_as_parent {
+ my $self = shift;
+ require POSIX;
+ $self->kill(POSIX::SIGUSR1());
+}
+
+sub _detach_as_child {
+ my $self = shift;
+ require POSIX;
+ $self->_detached( POSIX::setsid() )
+ || die "Cannot detach from parent $!";
+}
+
1;
__END__
@@ -407,12 +426,18 @@ Returns the coderef used to construct the Child.
Returns the parent processes PID. (Only in child)
+=item $child->detach()
+
+Detach the child from the parent. uses POSIX::setsid(). When called in the
+child it simply calls setsid. When called from the parent the USR1 signal is
+sent to the child which triggers the child to call setsid.
+
=back
=head1 HISTORY
Most of this was part of L<Parrallel::Runner> intended for use in the L<Fennec>
-project. Fennec is being brocken into multiple parts, this is one such part.
+project. Fennec is being broken into multiple parts, this is one such part.
=head1 FENNEC PROJECT
View
@@ -44,15 +44,22 @@ ok( $one->wait, "wait" );
ok( $one->is_complete, "Complete" );
is( $one->exit_status, 0, "Exit clean" );
-$one = $CLASS->new( sub {
- $SIG{INT} = sub { exit( 2 ) };
- sleep 100;
-})->start;
+$one = $CLASS->new( sub { sleep 100 } )->start;
my $ret = eval { $one->say("XXX"); 1 };
ok( !$ret, "Died, no IPC" );
like( $@, qr/Child was created without IPC support./, "No IPC" );
+$one->kill(2);
+$one = $CLASS->new( sub {
+ my $self = shift;
+ $SIG{INT} = sub { exit( 2 ) };
+ $self->say( "go" );
+ sleep 100;
+}, pipe => 1 )->start;
+
+$one->read;
+sleep 1;
ok( $one->kill(2), "Send signal" );
ok( !$one->wait, "wait" );
ok( $one->is_complete, "Complete" );
@@ -77,4 +84,27 @@ my $end = time;
ok( $end - $start > 2, "No autoflush" );
+$one = $CLASS->new( sub {
+ my $self = shift;
+ $self->detach;
+ $self->say( $self->detached );
+}, pipe => 1 )->start;
+
+is( $one->read(), $one->pid . "\n", "Child detached" );
+
+
+$one = $CLASS->new( sub {
+ my $self = shift;
+ $self->say( "go" );
+ $self->read;
+ $self->say( $self->detached );
+}, pipe => 1 )->start;
+
+$one->read();
+$one->detach;
+sleep 1;
+$one->say("go");
+
+is( $one->read(), $one->pid . "\n", "Child detached remotely" );
+
done_testing;

0 comments on commit e1ff7db

Please sign in to comment.