Package: yaret
Version: 2.1.0-4
Tags: patch

I experienced the same problem, that is, when using "no_normalize"
yaret would hang and never exit.

I tracked it down to the no_normalize child exiting so quickly (all it
does is execute "true"), that the yaret parent process had not even
registered the child as living before it died.  So the yaret parent
process registers it as living *after* it has already died, which
means it waits forever for a non-living child to die.

More specifically, in the make_kid subroutine, the parent process
forks and then registers the child as living with this line:

    $kid{$pid}{$type} = $read;

However, the no_normalize child process has already died by this point
(verified by inserting several debugging statements).  So I fixed it
by adding this line to the kid_killer subroutine:

  ++$dead{$deadone};

and then changed the line in the make_kid subroutine to this:

    $kid{$pid}{$type} = $read unless $dead{$pid};

Furthermore, I also had to update the alarm signal handler because it
was going off before the parent processed had entered a sleep state,
meaning that the parent process would sleep forever waiting for an
alarm signal that never came because it already went off.  So I
changed the code in several places (wherever the parent enters an
unlimited sleep state) to check for an alarm signal having already
gone off before going to sleep.

Attached is the full patch which can be applied to version 2.1.0-3 or
2.1.0-4.

By the way, a thank-you to the authors/maintainers of this program.  I
finally found a ripper that would use cdparanoia in "full paranoid
mode" and also automatically look up the tracks online.

Ken
--- yaret.orig  2006-02-20 17:01:51.290746777 +0000
+++ yaret       2006-02-20 17:06:05.973635770 +0000
@@ -449,6 +449,7 @@
 my %date; # start and end dates
 my %workfile; # these files are removed if we die suddenly
 my %kid; # keeps track of our children
+my %dead; # keeps track of dead children
 my %skip_track; # which tracks to skip
 my $cd; # Audio::CD interface to CD
 my $cd_info; # Audio::CD::Info object
@@ -456,6 +457,7 @@
 my $track = {}; # traslated Audio::CD::Info->tracks
 my %status; # holds the filehandles to read status from
 my $grand_dad = 1; # are we the main parent?
+my $alarm = 0; # set to 1 when an alarm signal is received
 
 sub kill_all {
   kill "SIGINT" => keys %kid;
@@ -468,11 +470,12 @@
 sub kid_killer {
   while ((my $deadone = waitpid(-1, WNOHANG)) > 0) {
     delete $kid{$deadone};
+    ++$dead{$deadone};
   }
 }
 
 sub set_default_signals {
-  $SIG{ALRM} = sub{};#'IGNORE';
+  $SIG{ALRM} = sub { $alarm = 1 };
   $SIG{CHLD} = \&kid_killer;
   $SIG{INT} = \&kill_all;
   $SIG{TERM} = \&kill_all;
@@ -860,7 +863,7 @@
   pipe $read, $write;
   if ( my $pid = fork ) { # I am the parent
     close $write;
-    $kid{$pid}{$type} = $read;
+    $kid{$pid}{$type} = $read unless $dead{$pid};
     return [$pid, $read];
   } else { # I am the child
     $0 = "$0 - ($type)";
@@ -1071,7 +1074,8 @@
   send_message($parent, type=>'startup');
   my @found;
   do {
-    sleep;
+    sleep unless $alarm;
+    $alarm = 0;
     my $glob = make_filename "*", $settings{from_name};
     @found = glob($glob);
     $workfile{$_} = 1 for @found;
@@ -1125,7 +1129,9 @@
   printc $INFO, "Waiting for work: \u$settings{name}\n";
   send_message($parent, type=>'startup');
   do {
-    sleep, check_message;
+    sleep unless $alarm;
+    $alarm = 0;
+    check_message;
     my $glob = make_filename "*", $settings{from_name};
     my $track_regex = make_filename '(\\d+)', $settings{from_name};
     $track_regex = '^'.$track_regex.'$';
@@ -1154,7 +1160,11 @@
       $my_kid{$filename} = make_kid $settings{name}."_kid", 
$settings{sub_call}, $track_num, %settings;
     }
   } while $done < keys %{$track};
-  (sleep, check_message) until kid_done $settings{name}."_kid";
+  until (kid_done $settings{name}."_kid") {
+      sleep unless $alarm;
+      $alarm = 0;
+      check_message;
+  };
 }
 
 sub send_signal {
@@ -1335,8 +1345,11 @@
   $status{group}{$encoder} = 'encoder';
 }
 
-sleep, print_status
-  until kid_done keys %{ $status{kid} };
+do {
+    sleep unless $alarm;
+    $alarm = 0;
+    print_status;
+} until kid_done keys %{ $status{kid} };
 
 rmdir $root_work;
 

Reply via email to