Skip Menu |

This queue is for tickets about the POE-Component-Child CPAN distribution.

Report information
The Basics
Id: 2720
Status: resolved
Worked: 5 min
Priority: 0/
Queue: POE-Component-Child

People
Owner: Nobody in particular
Requestors: poe [...] jbs.t0c.de
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: (no value)
Fixed in: (no value)



Subject: Can not read whole child output
The "done" event is emitted when SIGCHLD is received, even if there is child output that has not yet been processed. Due to this, the attached script produces unexpected output: --------------------------------- [run] Session 2 started. [run] Session 3 started. [run] Session 4 started. [run] Session 5 started. [run] Session 6 started. [run] Session 7 started. [run] Session 8 started. [run] Session 9 started. [run] Session 10 started. [run] Session 11 started. [end] Session 11 ended at 20 percent. [end] Session 10 ended at 37 percent. [end] Session 9 ended at 37 percent. [end] Session 8 ended at 37 percent. [end] Session 7 ended at 37 percent. [end] Session 6 ended at 37 percent. [end] Session 5 ended at 37 percent. [end] Session 4 ended at 37 percent. [end] Session 3 ended at 37 percent. [end] Session 2 ended at 37 percent. --------------------------------------------- My environment: * Linux * perl: 5.8.0 * POE: CVS
#!/usr/bin/perl use strict; use warnings; use POE qw(Component::Child); sub stdout { my ($self, $wheel) = @_; my $out = $wheel->{out}; my ($p) = $out =~ /(\d+)/; $self->{p} = $p; } sub done { my ($self) = @_; print "[end] Session $self->{session} ended at $self->{p} percent.\n"; } for( 1..10 ) { my $p = POE::Component::Child->new( callbacks => { stdout => \&stdout, done => \&done } ); $p->{p} = 0; $p->run( q`perl -e "for(1..1000){print int(\$_/10),qq'\n'}"` ); print "[run] Session $p->{session} started.\n"; } $poe_kernel->run();
I've verified this problem and it seems to be related to buffered output. replacing the ->run() line in the test script with: $p->run(q(perl -le '$|++; print int($_/10) for 1 .. 1000;')); seems to fix the problem. will consult with dngnand as to whether I should be throwing C<done> events on CloseEvent instead of sigchld. hope that helps...
consulted w/dngnand. patched so event is fired when _both_ the child's output pipes are closed _and_ the death signal is received.
oh yeah, latest version (1.28) at http://perl.arix.com