Hello,

    Ah, Let me fix a few bugs/typos in your code then it'll work as
intended!

    1. You do not need to run waitpid() yourself, POE::Kernel does it
for you :) To be precise, the sig_child event is delivered *after*
POE::Kernel has run waitpid. Maybe the
       docs need to be updated to make this very clear?

    2. In *any* signal handler ( other than sig_child, ha! ) you need to
let POE::Kernel know that it's OK to continue execution. This means
       you need to run POE::Kernel->sig_handled() in your sig handler (
event "down" ) or POE will commence shutdown operations. Again, the
POE::Kernel docs about signals
       are a lengthy read, but I believe it explains everything? In your
case, since you didn't do it the kernel shut down *before* it had a
chance to fire the sig_child event.

    3. In event "sig_child" you have a minor typo: $_[ARG1] not [ARG1]
heh :)

    4. Finally, in order to gracefully terminate the program you need to
delete the wheel in the "sig_child" event so the reference counts for
your session
       will go down and POE::Kernel will commence shutdown. This is
explained somewhat in the POE::Wheel::Run docs. ( also in POE::Wheel too )

    Here's a patch against your code that DWYMTD ( does what you meant
to do :) Yeah, coding stuff in POE takes a while to get your head around
because
there is a lot of things that interact. I know that the docs are HUGE
and doesn't necessarily explain everything. That's why dhoss++ and
rcaputo++ are working
on a new tutorial/book for POE. However, if you have ideas on how to
make the docs clearer - please let us know! Have fun hacking Perl/POE :)

~Apocalypse

a...@blackhole:~$ diff -urbd testsigchld_mike.pl testsigchld_myver.pl
--- testsigchld_mike.pl    2010-04-21 10:06:53.000000000 -0700
+++ testsigchld_myver.pl    2010-04-21 10:09:20.000000000 -0700
@@ -24,10 +24,11 @@
          down => sub {
              warn "killing process";
              $_[HEAP]->{wheel}->kill();
+             $_[KERNEL]->sig_handled();
          },
          sig_child => sub {
-             warn("waitpid for " . [ARG1]);
-             waitpid $_[ARG1], 0;
+             warn("child pid exited: " . $_[ARG1]);
+             delete $_[HEAP]->{wheel};
          },
      });


Mike Schilli wrote:
> I must be missing something obvious, as I'm getting
>
>     in start at ./wheel line 14.
>     starting ... at ./wheel line 27.
>     killing process at ./wheel line 30.
>     7353: !!! Child process PID:7354 reaped:
>     7353: !!! Your program may not be using sig_child() to reap
> processes.
>     7353: !!! In extreme cases, your program can force a system reboot
>     7353: !!! if this resource leakage is not corrected.
>
> although the code catches the sig_child:
>
>     use strict;
>     use warnings;
>     use POE;
>     use POE::Wheel::Run;
>
>     my $session = POE::Session->create(
>       inline_states => {
>           _start => sub {
>             warn "in start";
>             $_[HEAP]->{wheel} =
>             POE::Wheel::Run->new(
>               Program     => "sleep",
>               ProgramArgs => [60],
>               CloseEvent  => "closing",
>               ErrorEvent  => "closing",
>               StderrEvent => "ignore",
>             );
>
>             $poe_kernel->sig_child($_[HEAP]->{wheel}->PID,
>                                "sig_child");
>             $poe_kernel->sig( "INT"  => "down" );
>             warn "starting ...";
>          },
>          down => sub {
>              warn "killing process";
>              $_[HEAP]->{wheel}->kill();
>          },
>          sig_child => sub {
>              warn("waitpid for " . [ARG1]);
>              waitpid $_[ARG1], 0;
>          },
>      });
>
>     $poe_kernel->run();
>
> Looks like the 'sig_child' handler is never run ... suggestions?
>
> -- Mike
>
> Mike Schilli
> m...@perlmeister.com

Reply via email to