Hmmm. Interesting. So consider this:
I have a stream of data, which I'm sending to the POE::Wheel::Run process. At an arbitrary time I can get a signal that the stream has ended, at which point I want to shutdown the process's STDIN. If I knew the last bit of data sent was going to be the last bit of data, I could set a flag as I send it to the POE::Wheel::Run process, and then the next StdinEvent could call stdin_shutdown. But I don't know which bit of data is going to be the last. So when I receive the signal to shutdown STDIN, I don't know if the STDIN buffer is flushed or not (do I?). I can set a flag, but if it's already flushed, the StdinEvent will never get called. It seems I need a way to tell if there's anything pending in the buffer. Checking $wheel->get_stdin_filter->get_pending() seems like a good bet, but doesn't seem to be working -- it always seems to return false, even though if I then call stdin_shutdown the data never arrives at my process. Any suggestions? Am I missing something? Thanks, Dan On 12/21/04 3:18 PM, "Rocco Caputo" <[EMAIL PROTECTED]> wrote: > On Mon, Dec 20, 2004 at 10:44:23PM -0800, Dan McCormick wrote: >> >> Shouldn't the code below print 1, 2, 3, 4 on separate lines to the file >> /tmp/test.txt? >> >> If I comment out lines 537-538 of POE::Wheel::Run.pm, namely: >> >> $poe_kernel->select_pause_write($self->[HANDLE_STDIN]) >> unless ($self->[OCTETS_STDIN]); >> >> ... things work as (I) expected. Some cursory debugging suggests POE isn't >> flushing the buffer when the state returns, as the docs indicate. > > They don't quite work the way I expect, but I think you'll agree that > teh problem's over in shutdown_stdin() (around line 872): > > # Shutdown the pipe that leads to the child's STDIN. > sub shutdown_stdin { > my $self = shift; > return unless defined $self->[HANDLE_STDIN]; > > $poe_kernel->select_write($self->[HANDLE_STDIN], undef); > > eval { local $^W = 0; shutdown($self->[HANDLE_STDIN], 1) }; > close $self->[HANDLE_STDIN] if $@; > } > > The problem's fairly obvious. Your test case calls put() to prime the > STDIN buffer, then it calls shutdown_stdin() to close STDIN. > Unfortunately, the wheel also stops select_write() for the handle. > That prevents the buffer from ever being flushed. > > The proper thing to do is perhaps to set a shutdown flag if there is > pending input for the child process, and do the actual shutdown when > the input has flushed. > >> Also, even with the commented-out lines, it looks like I still need the >> 'doit' and 'shutdown' events to be separate (i.e., combining everything into >> the _start event doesn't work). Is that behavior intentional? > > I think it's creating a race condition where your expected behavior > occurs. It seems to be working only by coincidence.