File Coverage

lib/Rex/Fork/Manager.pm
Criterion Covered Total %
statement 45 54 83.3
branch 6 10 60.0
condition 1 3 33.3
subroutine 9 10 90.0
pod 0 6 0.0
total 61 83 73.4


line stmt bran cond sub pod time code
1             #
2             # (c) Jan Gehring
3             #
4              
5             package Rex::Fork::Manager;
6              
7 56     56   950 use v5.12.5;
  56         204  
8 56     56   339 use warnings;
  56         136  
  56         2551  
9              
10             our $VERSION = '1.14.2.3'; # TRIAL VERSION
11              
12 56     56   765 use Rex::Fork::Task;
  56         197  
  56         654  
13 56     56   2109 use Time::HiRes qw(sleep);
  56         117  
  56         531  
14              
15             sub new {
16 138     138 0 717 my $that = shift;
17 138   33     1374 my $proto = ref($that) || $that;
18 138         840 my $self = {@_};
19              
20 138         424 bless( $self, $proto );
21              
22 138         674 $self->{'forks'} = [];
23 138         428 $self->{'running'} = 0;
24              
25 138         462 return $self;
26             }
27              
28             sub add {
29 135     135 0 549 my ( $self, $coderef ) = @_;
30              
31 135         1375 my $f = Rex::Fork::Task->new( coderef => $coderef );
32              
33 135         350 push( @{ $self->{'forks'} }, $f );
  135         514  
34              
35 135         766 $f->start;
36 106         1439 ++$self->{'running'};
37              
38 106 50       2422 if ( $self->{'running'} >= $self->{'max'} ) {
39 106         3720 $self->wait_for_one;
40             }
41             }
42              
43             sub start {
44 0     0 0 0 my ($self) = @_;
45              
46 0         0 my @threads = @{ $self->{'forks'} };
  0         0  
47 0         0 for ( my $i = 0 ; $i < scalar(@threads) ; ++$i ) {
48 0         0 $threads[$i]->start;
49 0         0 ++$self->{'running'};
50 0 0       0 if ( $self->{'running'} >= $self->{'max'} ) {
51 0         0 $self->wait_for_one;
52             }
53             }
54              
55 0         0 $self->wait_for_all;
56             }
57              
58             sub wait_for_one {
59 106     106 0 1764 my ($self) = @_;
60 106         1693 $self->wait_for;
61             }
62              
63             sub wait_for_all {
64 107     107 0 897 my ($self) = @_;
65 107         936 $self->wait_for(1);
66             }
67              
68             sub wait_for {
69 213     213 0 994 my ( $self, $all ) = @_;
70             do {
71 6723         22896 FORK: for ( my $i = 0 ; $i < scalar( @{ $self->{'forks'} } ) ; $i++ ) {
  13339         160466  
72 6722         21807 my $thr = $self->{'forks'}->[$i];
73 6722 100       30889 unless ( $thr->{'running'} ) {
74 106         1063 next FORK;
75             }
76              
77 6616         16447 my $kid;
78 6616         72619 $kid = $thr->wait;
79              
80 6616 100       23720 if ( $kid == -1 ) {
81 106         551 $thr = undef;
82 106         3574 $thr->{running} = 0;
83 106         682 --$self->{'running'};
84              
85 106 50       4655 return 1 unless $all;
86             }
87 6510         64498 sleep Rex::Config->get_waitpid_blocking_sleep_time;
88             }
89 213         769 } until $self->{'running'} == 0;
90             }
91              
92             1;