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.


Reply via email to