-sub dwaitpid ($;$$) {
- my ($pid, $cb, $arg) = @_;
- if ($in_loop) {
- push @$wait_pids, [ $pid, $cb, $arg ];
- # We could've just missed our SIGCHLD, cover it, here:
- enqueue_reap();
- } else {
- my $ret = waitpid($pid, 0);
+sub requeue_once {
+ my ($self) = @_;
+ # COMPRESS users all share the same DEFLATE context.
+ # Flush it here to ensure clients don't see each other's data
+ $self->dflush;
+
+ # no recursion, schedule another call ASAP,
+ # but only after all pending writes are done.
+ # autovivify wbuf. wbuf may be populated by $cb,
+ # no need to rearm if so: (push returns new size of array)
+ $self->requeue if push(@{$self->{wbuf}}, \&long_step) == 1;
+}
+
+sub long_response ($$;@) {
+ my ($self, $cb, @args) = @_; # cb returns true if more, false if done
+ my $sock = $self->{sock} or return;
+ # make sure we disable reading during a long response,
+ # clients should not be sending us stuff and making us do more
+ # work while we are stream a response to them
+ $self->{long_cb} = [ fileno($sock), $cb, now(), @args ];
+ long_step($self); # kick off!
+ undef;
+}
+
+sub awaitpid {
+ my ($pid, @cb_args) = @_; # @cb_args = ($cb, @args), $cb may be undef
+ $AWAIT_PIDS->{$pid} = \@cb_args if @cb_args;
+ # provide synchronous API
+ if (defined(wantarray) || (!$in_loop && !@cb_args)) {
+ my $ret;
+again:
+ $ret = waitpid($pid, 0) // -2;