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

Reply via email to