--- Ext/Fork.pm.00 2009-12-19 06:00:59.000000000 -0800 +++ Ext/Fork.pm 2009-12-20 15:16:22.000000000 -0800 @@ -109,6 +109,7 @@ } while(1){ + rfork_cleanup(); if($Ext::Fork::POOL->{children} < $Ext::Fork::POOL->{max_children}){ last; } @@ -145,6 +146,7 @@ if($Ext::Fork::POOL->{has_children} && !$Ext::Fork::POOL->{nonblocking}){ while(1){ + rfork_cleanup(); last if !$Ext::Fork::POOL->{children}; if($Ext::Fork::has_thr){ rfork_usleep(500); @@ -195,8 +197,7 @@ sub _sigchld { while((my $p = waitpid(-1, WNOHANG)) > 0){ - delete $Ext::Fork::POOL->{cidlist}->{$p}; - $Ext::Fork::POOL->{children} -- if $Ext::Fork::POOL->{children}; + $Ext::Fork::POOL->{cidlist}->{$p} = 0; # mark process as done } # self reference @@ -243,6 +244,7 @@ return 1 if $Ext::Fork::POOL->{nonblocking}; while(1){ + rfork_cleanup(); last if !$Ext::Fork::POOL->{children}; if($Ext::Fork::has_thr){ @@ -262,6 +264,7 @@ =cut sub rfork_active_children { + rfork_cleanup(); return ($Ext::Fork::POOL->{children} ? $Ext::Fork::POOL->{children} : 0); } @@ -391,6 +394,7 @@ sub rfork_kill_children { my $sig = $_[0]; + rfork_cleanup(); if(!$sig){ $sig = 'TERM'; } @@ -410,6 +414,7 @@ sub rfork_list_children { my ($use_hash) = @_; + rfork_cleanup(); if(!$Ext::Fork::POOL->{cidlist}){ return; @@ -432,6 +437,7 @@ sub rfork_child_dob { my $pid = $_[0]; + rfork_cleanup(); if($Ext::Fork::POOL->{cidlist}->{$pid}){ return $Ext::Fork::POOL->{cidlist}->{$pid}; } else { @@ -439,4 +445,21 @@ } } +=head2 rfork_cleanup() + +Perform delayed list cleanup. + +=cut + +sub rfork_cleanup { + my @deadpids = + grep { $Ext::Fork::POOL->{cidlist}->{$_} == 0 } + keys %{ $Ext::Fork::POOL->{cidlist} }; + foreach (@deadpids) + { + delete $Ext::Fork::POOL->{cidlist}->{$_}; + $Ext::Fork::POOL->{children} -- if $Ext::Fork::POOL->{children}; + } +} +