AnyEvent and piped open

Marc Lehmann schmorp at schmorp.de
Fri Jul 15 08:49:31 CEST 2011


On Thu, Jul 14, 2011 at 12:09:03PM -0400, Laurent <laurent.aml at gmail.com> wrote:
> I am using AnyEvent/EV and try to catch the process termination of a piped open.

Your program is buggy - you poll for new events ($cv->recv) _before_
installing a child watcher. if your program exists before (very likely)
then the child simply doesn't exist anymore.

> This works when the child event is set before process termination, and
> fails if it is set after.

Not quite - it works when you start it before the process termination is
processed. Anything else would require the event loop to look into the
future (to know whether somebody will create a watcher for that child),
which is clearly a bit too complicated :)

Or to put it differently, the process *must* still exist when you create
the child watcher, otherwise the pid might belong to any random process
and you have a race.

> tprint "Wait for the process $pid to complete.\n";
> my $ev; $ev = AE::io $fd, 0, sub { my $b; sysread($fd, $b, 16); tprint
> "-- $b"; undef $ev; };
> my $cv = AE::cv;
> my $to = AE::timer 1, 0, sub { $cv->send; };
> $cv->recv;

  ^^^ bug happens here

> tprint "Now wait for the child sig.\n";
> $cv = AE::cv;
> $ev = AE::child $pid, sub { $cv->send("child"); };

> I would expect "Event received: child" in the 4th line.

That only works when you can guarantee that the child still exists. Since
that is practically impossible, you have to create the child watcher
before polling for child events.

-- 
                The choice of a       Deliantra, the free code+content MORPG
      -----==-     _GNU_              http://www.deliantra.net
      ----==-- _       generation
      ---==---(_)__  __ ____  __      Marc Lehmann
      --==---/ / _ \/ // /\ \/ /      schmorp at schmorp.de
      -=====/_/_//_/\_,_/ /_/\_\



More information about the anyevent mailing list