Classification:  UNCLASSIFIED 
Caveats: NONE

I've been cutting and pasting POE code for sometime now and though I still
don't understand a lot of it I've been able to use it successfully.  I'm now
working on a project in which I need to be able to capture the exit status
of child processes.  I'd really like to be able to have each child write to
a shared hash or array but I'm not sure if that's possible.

I have a script that's almost line for line the POE Cookbook "Child Process
3" example.  I saw the example in the FAQ for catching a child's exit status
with a signal handler but I'm not sure how to apply this to my code.
Specifically the hash of PIDs to wheels.

$heap->{pid_to_wheel}->{ $new_wheel->PID } = $new_wheel;
$heap->{id_to_wheel}->{ $new_wheel->ID }   = $new_wheel;  

Here's an example of how I tried to implement it....


POE::Session->create
  ( inline_states =>
    { _start => \&start_tasks,
      next_task   => \&start_tasks,
      task_result => \&handle_task_result,
      task_done   => \&handle_task_done,
      task_debug  => \&handle_task_debug,
      task_chld   => \&sigchld_handler,
    }
  );

sub start_tasks {
    my $heap = $_[HEAP];

    while ( keys( %{ $heap->{task} } ) < MAX_CONCURRENT_TASKS ) {
        my $next_task = shift @tasks;
        last unless defined $next_task;

        print "Starting task for $next_task...\n";

        my $task = POE::Wheel::Run->new
          ( Program => sub { do_stuff($next_task,@hosts) },
            StdioFilter  => POE::Filter::Line->new(),    # Child speaks in
lines.
            StderrFilter => POE::Filter::Line->new(),    # Child speaks in
lines.
            StdoutEvent  => "task_result",
            StderrEvent  => "task_debug",
            CloseEvent   => "task_done",
            ErrorEvent   => "task_chld",
          );

        $heap->{task}->{ $task->ID } = $task;
    }
}

sub do_stuff {
  my $task  = shift;
  my @hosts = @_;

  # The Crux
  foreach $host ( @hosts ) {
    $return_status = &main($host);
    if ( $return_status == 1 ) {
      exit 1;
    }
  }

}

.........
Other subs
..............

sub sigchld_handler {
    my ( $heap, $pid, $child_error ) = @_[ HEAP, ARG1, ARG2 ];
    return unless exists $heap->{pid_to_wheel}->{$pid};

    my $wheel = delete $heap->{pid_to_wheel}->{$pid};
    delete $heap->{id_to_wheel}->{ $wheel->ID };

    print(
        "child process $pid exited with status ",
        ( $child_error >> 8 ),
        "\n"
    );
}

# Run until there are no more devices.

$poe_kernel->run();

Any help would be great.
Classification:  UNCLASSIFIED 
Caveats: NONE

Reply via email to