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;
}
Attachment:
signature.asc
Description: OpenPGP digital signature