split out run_with_timeout()
authorDietmar Maurer <dietmar@proxmox.com>
Thu, 15 Dec 2011 10:24:05 +0000 (11:24 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Thu, 15 Dec 2011 10:25:45 +0000 (11:25 +0100)
Makefile
data/PVE/Tools.pm
debian/changelog

index 16e6f76..dfca640 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 RELEASE=2.0
 
 VERSION=1.0
-PKGREL=10
+PKGREL=11
 
 PACKAGE=libpve-common-perl
 
index 33f0de1..45fb621 100644 (file)
@@ -35,45 +35,78 @@ my $pvetaskdir = "$pvelogdir/tasks";
 mkdir $pvelogdir;
 mkdir $pvetaskdir;
 
-# flock: we use one file handle per process, so lock file
-# can be called multiple times and succeeds for the same process.
+sub run_with_timeout {
+    my ($timeout, $code, @param) = @_;
 
-my $lock_handles =  {};
+    die "got timeout\n" if $timeout <= 0;
 
-sub lock_file {
-    my ($filename, $timeout, $code, @param) = @_;
+    my $prev_alarm;
+
+    my $sigcount = 0;
 
     my $res;
 
-    $timeout = 10 if !$timeout;
+    local $SIG{ALRM} = sub { $sigcount++; }; # catch alarm outside eval
 
     eval {
+       local $SIG{ALRM} = sub { $sigcount++; die "got timeout\n"; };
+       local $SIG{PIPE} = sub { $sigcount++; die "broken pipe\n" };
+       local $SIG{__DIE__};   # see SA bug 4631
+
+       $prev_alarm = alarm($timeout);
+
+       $res = &$code(@param);
+
+       alarm(0); # avoid race conditions
+    };
+
+    my $err = $@;
+
+    alarm($prev_alarm) if defined($prev_alarm);
+
+    die "unknown error" if $sigcount && !$err; # seems to happen sometimes
+
+    die $err if $err;
+
+    return $res;
+}
 
-        local $SIG{ALRM} = sub { die "got timeout (can't lock '$filename')\n"; };
+# flock: we use one file handle per process, so lock file
+# can be called multiple times and succeeds for the same process.
 
-        alarm ($timeout);
+my $lock_handles =  {};
 
+sub lock_file {
+    my ($filename, $timeout, $code, @param) = @_;
+
+    $timeout = 10 if !$timeout;
+
+    my $lock_func = sub {
         if (!$lock_handles->{$$}->{$filename}) {
             $lock_handles->{$$}->{$filename} = new IO::File (">>$filename") ||
-                die "can't open lock file '$filename' - $!\n";
+                die "can't open file - $!\n";
         }
 
         if (!flock ($lock_handles->{$$}->{$filename}, LOCK_EX|LOCK_NB)) {
             print STDERR "trying to aquire lock...";
             if (!flock ($lock_handles->{$$}->{$filename}, LOCK_EX)) {
                 print STDERR " failed\n";
-                die "can't aquire lock for '$filename' - $!\n";
+                die "can't aquire lock - $!\n";
             }
             print STDERR " OK\n";
         }
-        alarm (0);
-
-        $res = &$code(@param);
     };
 
-    my $err = $@;
+    my $res;
 
-    alarm (0);
+    eval { run_with_timeout($timeout, $lock_func); };
+    my $err = $@;
+    if ($err) {
+       $err = "can't lock file '$filename' - $err";
+    } else {
+       eval { $res = &$code(@param) };
+       $err = $@;
+    }
 
     if ($lock_handles->{$$}->{$filename}) {
         my $fh = $lock_handles->{$$}->{$filename};
index 75c320c..4a50744 100644 (file)
@@ -1,3 +1,9 @@
+libpve-common-perl (1.0-11) unstable; urgency=low
+
+  * new helper run_with_timeout()
+
+ -- Proxmox Support Team <support@proxmox.com>  Thu, 15 Dec 2011 11:25:01 +0100
+
 libpve-common-perl (1.0-10) unstable; urgency=low
 
   * add helpers to implement migration