Index: ReadWrite.pm =================================================================== --- ReadWrite.pm (revision 2190) +++ ReadWrite.pm (working copy) @@ -28,6 +28,8 @@ sub STATE_WRITE () { 14 } sub STATE_READ () { 15 } sub UNIQUE_ID () { 16 } +sub PAUSE_INPUT () { 17 } +sub PAUSE_INPUT_QUEUE () { 18 } sub CRIMSON_SCOPE_HACK ($) { 0 } @@ -238,7 +240,7 @@ } #------------------------------------------------------------------------------ -# Redefine the select-read handler. This uses stupid closure tricks +# Redefine the select-read handler. This uses clever closure tricks # to prevent keeping extra references to $self around. sub _define_read_state { @@ -275,13 +277,13 @@ my ($k, $me, $handle) = @_[KERNEL, SESSION, ARG0]; if (defined(my $raw_input = $driver->get($handle))) { $$input_filter->get_one_start($raw_input); + my @recs; while (1) { my $next_rec = $$input_filter->get_one(); last unless @$next_rec; - foreach my $cooked_input (@$next_rec) { - $k->call($me, $$event_input, $cooked_input, $unique_id); - } + push @recs, @$next_rec; } + $self->_cook_input($me, $$input_filter, $$event_input, $unique_id, \@recs); } else { $$event_error and $k->call( @@ -307,9 +309,7 @@ # The actual code starts here. my ($k, $me, $handle) = @_[KERNEL, SESSION, ARG0]; if (defined(my $raw_input = $driver->get($handle))) { - foreach my $cooked_input (@{$$input_filter->get($raw_input)}) { - $k->call($me, $$event_input, $cooked_input, $unique_id); - } + $self->_cook_input($me, $$input_filter, $$event_input, $unique_id, $$input_filter->get($raw_input)); } else { $$event_error and $k->call( @@ -320,16 +320,32 @@ } ); } - # register the state's select + # register the state's select $poe_kernel->select_read($self->[HANDLE_INPUT], $self->[STATE_READ]); } - # undefine the select, just in case + # undefine the select, just in case else { $poe_kernel->select_read($self->[HANDLE_INPUT]) } } #------------------------------------------------------------------------------ +# +sub _cook_input { + my ($self, $filter, $me, $event, $uid, $records) = @_; + while ( my $record = shift @$records) { + if ( $self->[PAUSE_INPUT] ) { + unshift @$records, $record; + $self->[PAUSE_INPUT_QUEUE] = $records; + return; + } else { + $k->call($me, $event, $record, $uid); + } + } +} + + +#------------------------------------------------------------------------------ # Redefine events. sub event { @@ -595,12 +611,21 @@ sub pause_input { my $self = shift; return unless defined $self->[HANDLE_INPUT]; + $self->[PAUSE_INPUT] = 1; $poe_kernel->select_pause_read( $self->[HANDLE_INPUT] ); } # Resume the wheel's input watcher. sub resume_input { my $self = shift; + $self->[PAUSE_INPUT] = 0; + $self->_cook_input( # lets clear out the stack of crap we held up before + $self->[FILTER_INPUT], + $me, # ToDo: somehow we need to get the parent session here! + $self->[EVENT_INPUT], + $self->[UNIQUE_ID], + $self->[PAUSE_INPUT_QUEUE] + ); return unless defined $self->[HANDLE_INPUT]; $poe_kernel->select_resume_read( $self->[HANDLE_INPUT] ); }