diff options
author | Konstantin Ryabitsev <mricon@kernel.org> | 2011-11-28 10:57:40 -0500 |
---|---|---|
committer | Konstantin Ryabitsev <mricon@kernel.org> | 2011-11-28 10:57:40 -0500 |
commit | 042009addb09b18c102ecc26fabf0c0cecc5db21 (patch) | |
tree | 24e201856dd77a520da9d575d0aafbbd0f8b5311 | |
parent | ff54b4eb8b6a3b6a262f3b13e669c0b8d4799bcc (diff) | |
download | kup-042009addb09b18c102ecc26fabf0c0cecc5db21.tar.gz |
Another swing at the compression feedback.
Apply HPA's patch with a few tiny tweaks to make it work.
Use a notification pipe (simulated signalfd) to handle process exit,
thus allowing select() to handle timeouts as well as process
termination. This is functionally a workaround for Perl having
BSD-like retry behavior instead of EINTR behavior.
-rwxr-xr-x | kup-server | 35 |
1 files changed, 29 insertions, 6 deletions
@@ -628,17 +628,37 @@ sub make_compressed_data() # STDERR needs to be flushed STDERR->autoflush(1); + # A pipe to notify SIGCHLD + pipe(my $sigchldrd, my $sigchldwr) + or fatal("Failed to create notification pipe"); + + local $SIG{'CHLD'} = sub { + syswrite($sigchldwr, "\0", 1) + or fatal("Notification pipe write error"); + }; + + my $waitvec = ''; + vec($waitvec, fileno($sigchldrd),1) = 1; + + my $status_wait = 2; # Frequency of status updates + while ($nworkers) { - sleep(2); # Frequency of updates; my $w = waitpid(-1, WNOHANG); my $status = $?; - my $now = time(); - if ($now - $start_time >= $timeout_compress) { - foreach my $c (keys %workers) { - kill('TERM', $c); + if ($w == 0) { + my $now = time(); + if ($now - $start_time >= $timeout_compress) { + foreach my $c (keys %workers) { + kill('TERM', $c); + } + fatal("Timeout compressing output data"); + } + + if (select(my $wvout = $waitvec, undef, undef, $status_wait) == 1) { + # Drain the notification pipe + sysread($sigchldrd, my $junk, 1); } - fatal("Timeout compressing output data"); } my @ostr = (); @@ -673,6 +693,9 @@ sub make_compressed_data() } } + close($sigchldrd); + close($sigchldwr); + foreach my $fd (values %infds) { close($fd); } |