aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Ryabitsev <mricon@kernel.org>2011-11-28 10:57:40 -0500
committerKonstantin Ryabitsev <mricon@kernel.org>2011-11-28 10:57:40 -0500
commit042009addb09b18c102ecc26fabf0c0cecc5db21 (patch)
tree24e201856dd77a520da9d575d0aafbbd0f8b5311
parentff54b4eb8b6a3b6a262f3b13e669c0b8d4799bcc (diff)
downloadkup-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-xkup-server35
1 files changed, 29 insertions, 6 deletions
diff --git a/kup-server b/kup-server
index e2ac600..c24d5ae 100755
--- a/kup-server
+++ b/kup-server
@@ -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);
}