Hi Felix, I did a couple more testing and here are the results:
- Using the bpo kernel solves the issue - Using a smaller write on the read buffer solves the issue (tested with 4k) What does not solve the issue, that I've tried: - Writing only when the pipes are available for writing (using select on stdin). See the attached patch for the modification/tests I've made. The problem seems to be an interaction between the pipes, the process, perl and the kernel. Since bumping the kernel isn't an option for a lot users, I would suggest decreasing the read buffer (or writing smaller chunk?). -- Baptiste Beauplat - lyknode
--- /usr/share/perl5/Lintian/IO/Select.pm 2020-10-09 15:36:34.817261016 +0200 +++ /usr/share/lintian/lib/Lintian/IO/Select.pm 2020-10-09 15:38:11.944481974 +0200 @@ -77,7 +77,9 @@ my @pids; - my $select = IO::Select->new; + my $select_r = IO::Select->new; + my $select_w = IO::Select->new; + my $select_e = IO::Select->new; my $produce_stdin; my $produce_stdout; @@ -98,7 +100,8 @@ push(@pids, $produce_pid); - $select->add($produce_stdout, $produce_stderr); + $select_r->add($produce_stdout, $produce_stderr); + $select_e->add($produce_stdin, $produce_stdout, $produce_stderr); my $extract_stdin; my $extract_stdout; @@ -120,7 +123,9 @@ push(@pids, $extract_pid); - $select->add($extract_stdout, $extract_stderr); + $select_r->add($extract_stdout, $extract_stderr); + $select_w->add($extract_stdin); + $select_e->add($extract_stdin, $extract_stdout, $extract_stderr); my @index_options = qw(--list --verbose --utc --full-time --quoting-style=c --file -); @@ -140,7 +145,9 @@ push(@pids, $named_pid); - $select->add($named_stdout, $named_stderr); + $select_r->add($named_stdout, $named_stderr); + $select_w->add($named_stdin); + $select_e->add($named_stdin, $named_stdout, $named_stderr); my $numeric_stdin; my $numeric_stdout; @@ -159,7 +166,9 @@ push(@pids, $numeric_pid); - $select->add($numeric_stdout, $numeric_stderr); + $select_r->add($numeric_stdout, $numeric_stderr); + $select_w->add($numeric_stdin); + $select_e->add($numeric_stdin, $numeric_stdout, $numeric_stderr); my $named = EMPTY; my $numeric = EMPTY; @@ -168,12 +177,27 @@ my $extract_errors = EMPTY; my $named_errors = EMPTY; - while (my @ready = $select->can_read) { + use Data::Dumper; + while (my @state = IO::Select->select($select_r, $select_w, $select_e)) { + (my $read, my $write, my $error) = @state; + + for my $handle (@{$error}) { + die "PROCESS ERROR" + } + + my $count = scalar @{$write}; + if ($count != 3) { + STDERR->printflush("Not ready to write: $count: \n"); + next; + } else { + STDERR->printflush("OK to write\n"); + } - for my $handle (@ready) { + for my $handle (@{$read}) { my $buffer; - my $length = sysread($handle, $buffer, 4096 * TAR_RECORD_SIZE); + # my $length = sysread($handle, $buffer, 4096 * TAR_RECORD_SIZE); + my $length = sysread($handle, $buffer, 4096); die "Error from child: $!\n" unless defined $length; @@ -184,7 +208,7 @@ close $named_stdin; close $numeric_stdin; } - $select->remove($handle); + $select_r->remove($handle); next; }
signature.asc
Description: OpenPGP digital signature