Permalink
Browse files

Added class methods for managing all children

  • Loading branch information...
1 parent 02661d5 commit 7e164d887225e18ec511c8ef406065265c09d597 @exodist committed Jul 22, 2010
Showing with 86 additions and 4 deletions.
  1. +13 −1 README
  2. +44 −3 lib/Child.pm
  3. +29 −0 t/Manage.t
View
14 README
@@ -74,11 +74,23 @@ SYNOPSIS
my $message1 = $child->read(1);
-METHODS
+CLASS METHODS
+ @children = Child->all_children()
+ Get a list of all the children that have been started. This list is
+ cleared in children when they are started.
+
+ @pids = Child->all_child_pids()
+ Get a list of all the pids of children that have been started.
+
+ Child->wait_all()
+ Call wait() on all children.
+
+CONSTRUCTOR
$class->new( sub { ... } )
$class->new( sub { ... }, pipe => 1 )
Create a new Child object. Does not start the child.
+OBJECT METHODS
$child->start()
Start the child process.
View
@@ -3,8 +3,9 @@ use strict;
use warnings;
use Carp;
-our $VERSION = "0.002";
+our $VERSION = "0.003";
our %META;
+our @CHILDREN;
for my $reader ( qw/pid ipc exit code parent/ ) {
my $prop = "_$reader";
@@ -48,6 +49,19 @@ sub child(&;@) {
return __PACKAGE__->new($code, %{$META{$caller}}, %params )->start;
}
+sub all_children { @CHILDREN }
+
+sub all_child_pids {
+ my $class = shift;
+ map { $_->pid } $class->all_children;
+}
+
+sub wait_all {
+ my $class = shift;
+ $_->wait() for $class->all_children;
+ 1;
+}
+
sub new {
my ( $class, $code, %params ) = @_;
my %proto = ( _code => $code );
@@ -61,9 +75,11 @@ sub start {
my $parent = $$;
if ( my $pid = fork() ) {
$self->_pid( $pid );
+ push @CHILDREN => $self;
$self->_init_ipc if $self->ipc;
}
else {
+ @CHILDREN = ();
$self->_parent( $parent );
$self->_init_ipc if $self->ipc;
my $code = $self->code;
@@ -107,7 +123,7 @@ sub _wait {
my $x = 1;
do {
sleep(1) if defined $ret;
- $ret = waitpid( $self->pid, &POSIX::WNOHANG );
+ $ret = waitpid( $self->pid, $block ? 0 : &POSIX::WNOHANG );
} while ( $block && !$ret );
return 0 unless $ret;
croak( "wait returned $ret: No such process " . $self->pid )
@@ -271,7 +287,26 @@ How child() behaves regarding IPC is lexical to each importing class.
my $message1 = $child->read(1);
-=head1 METHODS
+=head1 CLASS METHODS
+
+=over 4
+
+=item @children = Child->all_children()
+
+Get a list of all the children that have been started. This list is cleared in
+children when they are started.
+
+=item @pids = Child->all_child_pids()
+
+Get a list of all the pids of children that have been started.
+
+=item Child->wait_all()
+
+Call wait() on all children.
+
+=back
+
+=head1 CONSTRUCTOR
=over 4
@@ -281,6 +316,12 @@ How child() behaves regarding IPC is lexical to each importing class.
Create a new Child object. Does not start the child.
+=back
+
+=head1 OBJECT METHODS
+
+=over
+
=item $child->start()
Start the child process.
View
@@ -0,0 +1,29 @@
+#!/usr/bin/perl;
+use strict;
+use warnings;
+
+use Test::More;
+our $CLASS = 'Child';
+require_ok( $CLASS );
+
+my @all = map { $CLASS->new(sub { 1 }) } 1 .. 4;
+my @get = $CLASS->all_children;
+is( @get, 0, "0 children started" );
+
+$_->start for @all;
+
+@get = $CLASS->all_children;
+is( @get, 4, "4 children" );
+is_deeply( \@get, \@all, "Exact list" );
+
+is_deeply(
+ [ $CLASS->all_child_pids ],
+ [ map { $_->pid } @all ],
+ "pids"
+);
+
+is( $_->exit(), undef, "Not waited " . $_->pid ) for @all;
+$CLASS->wait_all();
+ok( defined($_->exit()), "waited " . $_->pid ) for @all;
+
+done_testing;

0 comments on commit 7e164d8

Please sign in to comment.