Specifying {cb_args} in the options hash felt awkward to me.
Instead, just use the Perl stack like we do with awaitpid()
and pass the list down directly.
my ($r, $w) = @{delete $lei->{zpipe}};
my $rdr = { 0 => $r, 1 => $lei->{1}, 2 => $lei->{2}, pgid => 0 };
my $pid = spawn($cmd, undef, $rdr);
- $lei->{1} = PublicInbox::ProcessIO->maybe_new($pid, $w, {
- cb_arg => [\&reap_compress, $lei, $cmd, $lei->{1} ] });
+ $lei->{1} = PublicInbox::ProcessIO->maybe_new($pid, $w,
+ \&reap_compress, $lei, $cmd, $lei->{1});
}
# --augment existing output destination, with deduplication
use Symbol qw(gensym);
sub maybe_new {
- my ($cls, $pid, $fh, $opt) = @_;
+ my ($cls, $pid, $fh, @cb_arg) = @_;
return ($fh, $pid) if wantarray;
my $s = gensym;
- tie *$s, $cls, $pid, $fh, @{$opt->{cb_arg} // []};
+ tie *$s, $cls, $pid, $fh, @cb_arg;
$s;
}
}
$self->{cmd} = $cmd;
$self->{-quiet} = 1 if $o{quiet};
- $o{cb_arg} = [ \&waitpid_err, $self ];
eval {
# popen_rd may die on EMFILE, ENFILE
- $self->{rpipe} = popen_rd($cmd, $cmd_env, \%o) // die "E: $!";
+ $self->{rpipe} = popen_rd($cmd, $cmd_env, \%o,
+ \&waitpid_err, $self);
$limiter->{running}++;
$start_cb->($self); # EPOLL_CTL_ADD may ENOSPC/ENOMEM
};
}
sub popen_rd {
- my ($cmd, $env, $opt) = @_;
+ my ($cmd, $env, $opt, @cb_arg) = @_;
pipe(my $r, local $opt->{1}) or die "pipe: $!\n";
- PublicInbox::ProcessIO->maybe_new(spawn($cmd, $env, $opt), $r, $opt)
+ my $pid = spawn($cmd, $env, $opt);
+ PublicInbox::ProcessIO->maybe_new($pid, $r, @cb_arg);
}
sub popen_wr {
- my ($cmd, $env, $opt) = @_;
+ my ($cmd, $env, $opt, @cb_arg) = @_;
pipe(local $opt->{0}, my $w) or die "pipe: $!\n";
- PublicInbox::ProcessIO->maybe_new(spawn($cmd, $env, $opt), $w, $opt)
+ my $pid = spawn($cmd, $env, $opt);
+ PublicInbox::ProcessIO->maybe_new($pid, $w, @cb_arg)
}
sub run_wait ($;$$) {
{ # ->CLOSE vs ->DESTROY waitpid caller distinction
my @c;
- my $fh = popen_rd(['true'], undef, { cb_arg => [sub { @c = caller }] });
+ my $fh = popen_rd(['true'], undef, undef, sub { @c = caller });
ok(close($fh), '->CLOSE fired and successful');
ok(scalar(@c), 'callback fired by ->CLOSE');
ok(grep(!m[/PublicInbox/DS\.pm\z], @c), 'callback not invoked by DS');
@c = ();
- $fh = popen_rd(['true'], undef, { cb_arg => [sub { @c = caller }] });
+ $fh = popen_rd(['true'], undef, undef, sub { @c = caller });
undef $fh; # ->DESTROY
ok(scalar(@c), 'callback fired by ->DESTROY');
ok(grep(!m[/PublicInbox/ProcessIO\.pm\z], @c),
use POSIX qw(_exit);
pipe(my ($r, $w)) or BAIL_OUT $!;
my @arg;
- my $cb = [ sub { @arg = @_; warn "x=$$\n" }, 'hi' ];
- my $fh = popen_rd(['cat'], undef, { 0 => $r, cb_arg => $cb });
+ my $fh = popen_rd(['cat'], undef, { 0 => $r },
+ sub { @arg = @_; warn "x=$$\n" }, 'hi');
my $pp = tied *$fh;
my $pid = fork // BAIL_OUT $!;
local $SIG{__WARN__} = sub { _exit(1) };