| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# See copyright, etc in below POD section. |
|
2
|
|
|
|
|
|
|
###################################################################### |
|
3
|
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
package Parallel::Forker::Process; |
|
5
|
|
|
|
|
|
|
require 5.006; |
|
6
|
34
|
|
|
34
|
|
223
|
use Carp qw(carp croak confess); |
|
|
34
|
|
|
|
|
68
|
|
|
|
34
|
|
|
|
|
1780
|
|
|
7
|
34
|
|
|
34
|
|
172
|
use IO::File; |
|
|
34
|
|
|
|
|
62
|
|
|
|
34
|
|
|
|
|
3966
|
|
|
8
|
34
|
|
|
34
|
|
18871
|
use POSIX qw(sys_wait_h :signal_h); |
|
|
34
|
|
|
|
|
223503
|
|
|
|
34
|
|
|
|
|
185
|
|
|
9
|
34
|
|
|
34
|
|
74804
|
use Proc::ProcessTable; |
|
|
34
|
|
|
|
|
169298
|
|
|
|
34
|
|
|
|
|
1627
|
|
|
10
|
34
|
|
|
34
|
|
248
|
use Scalar::Util qw(weaken); |
|
|
34
|
|
|
|
|
41
|
|
|
|
34
|
|
|
|
|
1469
|
|
|
11
|
|
|
|
|
|
|
|
|
12
|
34
|
|
|
34
|
|
176
|
use strict; |
|
|
34
|
|
|
|
|
50
|
|
|
|
34
|
|
|
|
|
740
|
|
|
13
|
34
|
|
|
34
|
|
141
|
use vars qw($Debug $VERSION $HashId); |
|
|
34
|
|
|
|
|
45
|
|
|
|
34
|
|
|
|
|
79413
|
|
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
$VERSION = '1.258'; |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
$Debug = $Parallel::Forker::Debug; |
|
18
|
|
|
|
|
|
|
$HashId = 0; |
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
sub _new { |
|
21
|
414
|
|
|
414
|
|
752
|
my $class = shift; |
|
22
|
|
|
|
|
|
|
my $self = { |
|
23
|
|
|
|
|
|
|
_forkref => undef, # Upper Fork object |
|
24
|
|
|
|
|
|
|
name => $HashId++, # ID for hashing. User may override it |
|
25
|
|
|
|
|
|
|
label => undef, # Label for run_after's |
|
26
|
|
|
|
|
|
|
_after_children => {}, # IDs that are waiting on this event |
|
27
|
|
|
|
|
|
|
_after_parents => {}, # IDs that we need to wait for |
|
28
|
|
|
|
|
|
|
_state => 'idle', # 'idle', 'ready', 'runable', 'running', 'done', 'parerr' |
|
29
|
|
|
|
|
|
|
_ref_count => 0, # number of people depending on us |
|
30
|
|
|
|
|
|
|
pid => undef, # Pid # running as, undef=not running |
|
31
|
|
|
|
|
|
|
run_after => [], # Process objects that are prereqs |
|
32
|
|
|
|
223
|
|
|
run_pre_start => sub {}, |
|
33
|
0
|
|
|
0
|
|
0
|
run_on_start => sub {confess "%Error: No run_on_start defined\n";}, |
|
34
|
0
|
|
|
0
|
|
0
|
run_on_finish => sub {my ($procref,$status) = @_;}, # Routine taking child and exit status |
|
35
|
|
|
|
|
|
|
@_ |
|
36
|
414
|
|
|
|
|
8435
|
}; |
|
37
|
414
|
|
|
|
|
1930
|
$Debug = $Parallel::Forker::Debug; |
|
38
|
414
|
|
33
|
|
|
2411
|
bless $self, ref($class)||$class; |
|
39
|
|
|
|
|
|
|
# Users need to delete the old one first, if they care. |
|
40
|
|
|
|
|
|
|
# We don't do that automatically, as generally this is a mistake, and |
|
41
|
|
|
|
|
|
|
# deleting the old one may terminate a process or have other nasty effects. |
|
42
|
|
|
|
|
|
|
(!exists $self->{_forkref}{_processes}{$self->{name}}) |
|
43
|
414
|
50
|
|
|
|
1480
|
or croak "%Error: Creating a new process under the same name as an existing process: $self->{name},"; |
|
44
|
414
|
|
|
|
|
1275
|
$self->{_forkref}{_processes}{$self->{name}} = $self; |
|
45
|
414
|
|
|
|
|
1553
|
weaken($self->{_forkref}); |
|
46
|
|
|
|
|
|
|
|
|
47
|
414
|
100
|
|
|
|
921
|
if (defined $self->{label}) { |
|
48
|
108
|
50
|
|
|
|
308
|
if (ref $self->{label}) { |
|
49
|
0
|
|
|
|
|
0
|
foreach my $label (@{$self->{label}}) { |
|
|
0
|
|
|
|
|
0
|
|
|
50
|
0
|
|
|
|
|
0
|
push @{$self->{_forkref}{_labels}{$label}}, $self; |
|
|
0
|
|
|
|
|
0
|
|
|
51
|
|
|
|
|
|
|
} |
|
52
|
|
|
|
|
|
|
} else { |
|
53
|
108
|
|
|
|
|
172
|
push @{$self->{_forkref}{_labels}{$self->{label}}}, $self; |
|
|
108
|
|
|
|
|
414
|
|
|
54
|
|
|
|
|
|
|
} |
|
55
|
|
|
|
|
|
|
} |
|
56
|
414
|
|
|
|
|
1174
|
$self->_calc_runable; # Recalculate |
|
57
|
414
|
|
|
|
|
1111
|
return $self; |
|
58
|
|
|
|
|
|
|
} |
|
59
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
sub DESTROY { |
|
61
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
|
62
|
0
|
|
|
|
|
0
|
delete $self->{_forkref}{_processes}{$self->{name}}; |
|
63
|
|
|
|
|
|
|
} |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
##### ACCESSORS |
|
66
|
|
|
|
|
|
|
|
|
67
|
301
|
|
|
301
|
1
|
5804
|
sub name { return $_[0]->{name}; } |
|
68
|
0
|
|
|
0
|
1
|
0
|
sub label { return $_[0]->{label}; } |
|
69
|
0
|
|
|
0
|
1
|
0
|
sub pid { return $_[0]->{pid}; } |
|
70
|
0
|
|
|
0
|
1
|
0
|
sub status { return $_[0]->{status}; } # Maybe undef |
|
71
|
234
|
|
66
|
234
|
1
|
7220
|
sub status_ok { return defined $_[0]->{status} && $_[0]->{status}==0; } |
|
72
|
0
|
|
|
0
|
1
|
0
|
sub forkref { return $_[0]->{_forkref}; } |
|
73
|
|
|
|
|
|
|
|
|
74
|
0
|
|
|
0
|
1
|
0
|
sub state { return $_[0]->{_state}; } |
|
75
|
525
|
|
|
525
|
1
|
3828
|
sub is_idle { return $_[0]->{_state} eq 'idle'; } |
|
76
|
525
|
|
|
525
|
1
|
2690
|
sub is_ready { return $_[0]->{_state} eq 'ready'; } |
|
77
|
0
|
|
|
0
|
1
|
0
|
sub is_runable { return $_[0]->{_state} eq 'runable'; } |
|
78
|
223
|
|
|
223
|
1
|
2459
|
sub is_running { return $_[0]->{_state} eq 'running'; } |
|
79
|
1446
|
|
|
1446
|
1
|
30047
|
sub is_done { return $_[0]->{_state} eq 'done'; } |
|
80
|
754
|
|
|
754
|
1
|
11004
|
sub is_parerr { return $_[0]->{_state} eq 'parerr'; } |
|
81
|
|
|
|
|
|
|
sub is_reapable { |
|
82
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
|
83
|
0
|
|
0
|
|
|
0
|
return $self->{_ref_count} == 0 && ($self->is_done || $self->is_parerr); |
|
84
|
|
|
|
|
|
|
} |
|
85
|
|
|
|
|
|
|
|
|
86
|
394
|
|
|
394
|
0
|
1020
|
sub reference { $_[0]->{_ref_count}++ } |
|
87
|
294
|
|
|
294
|
0
|
1639
|
sub unreference { $_[0]->{_ref_count}-- } |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
##### METHODS |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
sub _calc_eqns { |
|
92
|
414
|
|
|
414
|
|
591
|
my $self = shift; |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
# Convert references to names of the reference |
|
95
|
|
|
|
|
|
|
$self->{run_after} = [map |
|
96
|
|
|
|
|
|
|
{ |
|
97
|
394
|
100
|
|
|
|
1061
|
if (ref $_) { $_ = $_->{name} }; |
|
|
96
|
|
|
|
|
374
|
|
|
98
|
394
|
|
|
|
|
1502
|
$_; |
|
99
|
414
|
|
|
|
|
711
|
} @{$self->{run_after}} ]; |
|
|
414
|
|
|
|
|
995
|
|
|
100
|
|
|
|
|
|
|
|
|
101
|
414
|
|
|
|
|
934
|
my $run_after = (join " & ", @{$self->{run_after}}); |
|
|
414
|
|
|
|
|
1323
|
|
|
102
|
414
|
|
|
|
|
3342
|
$run_after =~ s/([&\|\!\^\---\(\)])/ $1 /g; |
|
103
|
414
|
50
|
50
|
|
|
1380
|
print " FrkRunafter $self->{name}: $run_after\n" if ($Debug||0)>=2; |
|
104
|
|
|
|
|
|
|
|
|
105
|
414
|
|
|
|
|
680
|
my $runable_eqn = ""; |
|
106
|
414
|
|
|
|
|
660
|
my $parerr_eqn = ""; |
|
107
|
414
|
|
|
|
|
565
|
my $ignerr; |
|
108
|
414
|
|
|
|
|
857
|
my $flip_op = ''; # ~ or ^ or empty |
|
109
|
414
|
|
|
|
|
658
|
my $between_op = '&&'; |
|
110
|
414
|
|
|
|
|
583
|
my $between_op_not = '||'; |
|
111
|
414
|
|
|
|
|
685
|
my $need_op_next = 0; |
|
112
|
414
|
|
|
|
|
631
|
my $any_refs = 0; |
|
113
|
414
|
|
|
|
|
3107
|
foreach my $token (split /\s+/, " $run_after ") { |
|
114
|
980
|
100
|
|
|
|
3965
|
next if $token =~ /^\s*$/; |
|
115
|
|
|
|
|
|
|
#print "TOKE $token\n" if $Debug; |
|
116
|
657
|
100
|
100
|
|
|
5995
|
if ($token eq '!' || $token eq '^') { |
|
|
|
100
|
33
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
117
|
64
|
|
|
|
|
258
|
$flip_op = $token; |
|
118
|
|
|
|
|
|
|
} elsif ($token eq '-') { |
|
119
|
32
|
|
|
|
|
138
|
$ignerr = 1; |
|
120
|
|
|
|
|
|
|
} elsif ($token eq '(' || $token eq ')') { |
|
121
|
0
|
0
|
|
|
|
0
|
if ($token eq '(') { |
|
122
|
0
|
0
|
|
|
|
0
|
$runable_eqn .= " ${between_op}" if $need_op_next; |
|
123
|
0
|
0
|
|
|
|
0
|
$parerr_eqn .= " ${between_op_not}" if $need_op_next; |
|
124
|
0
|
|
|
|
|
0
|
$need_op_next = 0; |
|
125
|
|
|
|
|
|
|
} |
|
126
|
0
|
|
|
|
|
0
|
$runable_eqn .= " $token "; |
|
127
|
0
|
|
|
|
|
0
|
$parerr_eqn.= " $token "; |
|
128
|
|
|
|
|
|
|
} elsif ($token eq '&') { |
|
129
|
71
|
|
|
|
|
174
|
$between_op = '&&'; $between_op_not = '||'; |
|
|
71
|
|
|
|
|
156
|
|
|
130
|
|
|
|
|
|
|
} elsif ($token eq '|') { |
|
131
|
64
|
|
|
|
|
156
|
$between_op = '||'; $between_op_not = '&&'; |
|
|
64
|
|
|
|
|
124
|
|
|
132
|
|
|
|
|
|
|
} elsif ($token =~ /^[a-z0-9_]*$/i) { |
|
133
|
|
|
|
|
|
|
# Find it |
|
134
|
426
|
|
|
|
|
1908
|
my @found = $self->{_forkref}->find_proc_name($token); |
|
135
|
426
|
100
|
|
|
|
1145
|
if (defined $found[0]) { |
|
136
|
394
|
|
|
|
|
769
|
foreach my $aftref (@found) { |
|
137
|
394
|
|
|
|
|
754
|
my $aftname = $aftref->{name}; |
|
138
|
394
|
50
|
|
|
|
1406
|
($aftref ne $self) or die "%Error: Id $self->{name} has a run_after on itself; it will never start\n"; |
|
139
|
394
|
100
|
|
|
|
899
|
$runable_eqn .= " ${between_op}" if $need_op_next; |
|
140
|
394
|
100
|
|
|
|
964
|
$parerr_eqn .= " ${between_op_not}" if $need_op_next; |
|
141
|
|
|
|
|
|
|
# _ranok, _ranfail, _nofail |
|
142
|
394
|
100
|
|
|
|
963
|
if ($flip_op eq '!') { |
|
|
|
100
|
|
|
|
|
|
|
143
|
32
|
|
|
|
|
208
|
$runable_eqn .= " (_ranfail('$aftname')||_parerr('$aftname'))"; |
|
144
|
32
|
|
|
|
|
96
|
$parerr_eqn .= " (_ranok('$aftname'))"; |
|
145
|
|
|
|
|
|
|
} elsif ($flip_op eq '^') { |
|
146
|
32
|
|
|
|
|
432
|
$runable_eqn .= " (_ranok('$aftname')||_ranfail('$aftname')||_parerr('$aftname'))"; |
|
147
|
32
|
|
|
|
|
60
|
$parerr_eqn .= " (0)"; |
|
148
|
|
|
|
|
|
|
} else { |
|
149
|
330
|
|
|
|
|
884
|
$runable_eqn .= " (_ranok('$aftname'))"; |
|
150
|
330
|
|
|
|
|
889
|
$parerr_eqn .= " (_ranfail('$aftname')||_parerr('$aftname'))"; |
|
151
|
|
|
|
|
|
|
} |
|
152
|
|
|
|
|
|
|
|
|
153
|
394
|
|
|
|
|
1114
|
$aftref->{_after_children}{$self->{name}} = $self; |
|
154
|
394
|
|
|
|
|
806
|
$self->{_after_parents}{$aftref->{name}} = $aftref; |
|
155
|
394
|
|
|
|
|
1715
|
weaken($aftref->{_after_children}{$self->{name}}); |
|
156
|
394
|
|
|
|
|
1241
|
weaken($self->{_after_parents}{$aftref->{name}}); |
|
157
|
|
|
|
|
|
|
|
|
158
|
394
|
100
|
50
|
|
|
798
|
my $apo = $flip_op; $apo ||= 'O' if $between_op eq '||'; |
|
|
394
|
|
|
|
|
1502
|
|
|
159
|
394
|
100
|
100
|
|
|
1601
|
$apo ||= '&'; $apo='E' if $apo eq '!'; |
|
|
394
|
|
|
|
|
1061
|
|
|
160
|
394
|
|
|
|
|
1261
|
$self->{_after_parents_op}{$aftref->{name}} = $apo; |
|
161
|
394
|
|
|
|
|
673
|
$need_op_next = 1; |
|
162
|
394
|
|
|
|
|
877
|
$any_refs = 1; |
|
163
|
|
|
|
|
|
|
} |
|
164
|
|
|
|
|
|
|
} else { |
|
165
|
32
|
50
|
|
|
|
110
|
if ($ignerr) { |
|
166
|
32
|
50
|
|
|
|
1776
|
print " FrkProc $self->{name} run_after process/label $token not found ignored.\n" if $Debug; |
|
167
|
|
|
|
|
|
|
} else { |
|
168
|
0
|
|
|
|
|
0
|
croak "%Error: run_after process/label $token not found,"; |
|
169
|
|
|
|
|
|
|
} |
|
170
|
|
|
|
|
|
|
} |
|
171
|
|
|
|
|
|
|
# Prep for next |
|
172
|
426
|
|
|
|
|
806
|
$ignerr = 0; |
|
173
|
426
|
|
|
|
|
1185
|
$flip_op = ''; |
|
174
|
|
|
|
|
|
|
} else { |
|
175
|
0
|
|
|
|
|
0
|
croak "%Error: run_after parse error of $token in: $run_after,"; |
|
176
|
|
|
|
|
|
|
} |
|
177
|
|
|
|
|
|
|
} |
|
178
|
414
|
100
|
|
|
|
1259
|
$runable_eqn = "1" if !$any_refs; |
|
179
|
414
|
100
|
|
|
|
963
|
$parerr_eqn = "0" if !$any_refs; |
|
180
|
414
|
|
|
|
|
973
|
$self->{_runafter_text} = $run_after; |
|
181
|
414
|
|
|
|
|
919
|
$self->{_runable_eqn_text} = $runable_eqn; |
|
182
|
414
|
|
|
|
|
1140
|
$self->{_parerr_eqn_text} = $parerr_eqn; |
|
183
|
414
|
|
|
|
|
1326
|
my $set = ("\t\$self->{_runable_eqn} = sub { return $runable_eqn; };\n" |
|
184
|
|
|
|
|
|
|
."\t\$self->{_parerr_eqn} = sub { return $parerr_eqn; };1;\n"); |
|
185
|
414
|
50
|
50
|
|
|
1410
|
print "$set" if ($Debug||0)>=2; |
|
186
|
414
|
50
|
|
|
|
68744
|
eval $set or die ("%Error: Can't eval:\n$@\n" |
|
187
|
|
|
|
|
|
|
." $self->{_runafter_text}\n $self->{_runable_eqn_text}\n $self->{_parerr_eqn_text}\n"); |
|
188
|
|
|
|
|
|
|
} |
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
sub ready { |
|
191
|
414
|
|
|
414
|
1
|
952
|
my $self = shift; |
|
192
|
|
|
|
|
|
|
# User is indicating ready. |
|
193
|
414
|
50
|
|
|
|
1145
|
($self->{_state} eq 'idle') or croak "%Error: Signalling ready to already ready process,"; |
|
194
|
|
|
|
|
|
|
|
|
195
|
414
|
|
|
|
|
1179
|
$self->_calc_eqns; |
|
196
|
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
# Transition: idle -> 'ready' |
|
198
|
414
|
50
|
|
|
|
16463
|
print " FrkProc $self->{name} $self->{_state} -> ready\n" if $Debug; |
|
199
|
414
|
50
|
|
|
|
2559
|
if (not $self->is_ready) { |
|
200
|
414
|
|
|
|
|
692
|
$_->reference for values %{$self->{_after_parents}}; |
|
|
414
|
|
|
|
|
2361
|
|
|
201
|
|
|
|
|
|
|
} |
|
202
|
414
|
|
|
|
|
1050
|
$self->{_state} = 'ready'; |
|
203
|
414
|
|
|
|
|
1063
|
$self->_calc_runable; |
|
204
|
|
|
|
|
|
|
} |
|
205
|
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
sub parerr { |
|
207
|
111
|
|
|
111
|
0
|
380
|
my $self = shift; |
|
208
|
|
|
|
|
|
|
# Mark process as never to be run |
|
209
|
111
|
50
|
33
|
|
|
453
|
if ($self->is_idle || $self->is_ready) { |
|
210
|
111
|
50
|
|
|
|
5272
|
print " FrkProc $self->{name} $self->{_state} -> parerr\n" if $Debug; |
|
211
|
111
|
|
|
|
|
636
|
$self->{_state} = 'parerr'; # "can't run due to parent status" is more accurate |
|
212
|
|
|
|
|
|
|
} else { |
|
213
|
0
|
|
|
|
|
0
|
croak "%Error: process isn't ready\n"; |
|
214
|
|
|
|
|
|
|
} |
|
215
|
|
|
|
|
|
|
# May need to spawn/kill children |
|
216
|
111
|
|
|
|
|
295
|
foreach my $ra (values %{$self->{_after_children}}) { |
|
|
111
|
|
|
|
|
830
|
|
|
217
|
111
|
|
|
|
|
756
|
$ra->_calc_runable; |
|
218
|
|
|
|
|
|
|
} |
|
219
|
|
|
|
|
|
|
} |
|
220
|
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
sub run { |
|
222
|
223
|
|
|
223
|
1
|
780
|
my $self = shift; |
|
223
|
|
|
|
|
|
|
# Transition: Any state -> 'running', ignoring run_after's |
|
224
|
223
|
50
|
|
|
|
737
|
!$self->{pid} or croak "%Error: process is already running,"; |
|
225
|
223
|
50
|
|
|
|
1744
|
!$self->is_running or croak "%Error: process is already running,"; |
|
226
|
|
|
|
|
|
|
|
|
227
|
223
|
50
|
|
|
|
12059
|
print " FrkProc $self->{name} $self->{_state} -> running\n" if $Debug; |
|
228
|
223
|
|
|
|
|
2523
|
$self->{_state} = 'running'; |
|
229
|
223
|
|
|
|
|
1783
|
$self->{start_time} = time(); |
|
230
|
223
|
|
|
|
|
2544
|
$self->{run_pre_start}->($self); |
|
231
|
223
|
100
|
|
|
|
236986
|
if (my $pid = fork()) { |
|
232
|
195
|
|
|
|
|
4287
|
$self->{pid} = $pid; |
|
233
|
195
|
|
|
|
|
7137
|
$self->{pid_last_run} = $pid; |
|
234
|
195
|
|
|
|
|
10709
|
$self->{_forkref}{_running}{$self->{pid}} = $self; |
|
235
|
195
|
|
|
|
|
6000
|
delete $self->{_forkref}{_runable}{$self->{name}}; |
|
236
|
|
|
|
|
|
|
} else { |
|
237
|
28
|
|
|
|
|
5437
|
$self->{run_on_start}->($self); |
|
238
|
23
|
|
|
|
|
842839
|
exit(0); # Don't close anything |
|
239
|
|
|
|
|
|
|
} |
|
240
|
195
|
|
|
|
|
8389
|
return $self; # So can chain commands |
|
241
|
|
|
|
|
|
|
} |
|
242
|
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
sub run_after { |
|
244
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
|
245
|
|
|
|
|
|
|
# @_ = objects to add as prereqs |
|
246
|
0
|
0
|
|
|
|
0
|
($self->{_state} eq 'idle') or croak "%Error: Must set run_after's before marking the process ready,"; |
|
247
|
0
|
|
|
|
|
0
|
push @{$self->{run_after}}, @_; |
|
|
0
|
|
|
|
|
0
|
|
|
248
|
0
|
|
|
|
|
0
|
return $self; # So can chain commands |
|
249
|
|
|
|
|
|
|
} |
|
250
|
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
sub reap { |
|
252
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
|
253
|
|
|
|
|
|
|
|
|
254
|
0
|
0
|
|
|
|
0
|
$self->is_reapable or croak "%Error: process is not reapable,"; |
|
255
|
0
|
|
|
|
|
0
|
delete $self->{_forkref}{_processes}{$self->{name}}; |
|
256
|
0
|
0
|
|
|
|
0
|
if (defined $self->{label}) { |
|
257
|
0
|
0
|
|
|
|
0
|
if (ref $self->{label}) { |
|
258
|
0
|
|
|
|
|
0
|
foreach my $label (@{$self->{label}}) { |
|
|
0
|
|
|
|
|
0
|
|
|
259
|
0
|
|
|
|
|
0
|
@{$self->{_forkref}{_labels}{$label}} = |
|
260
|
0
|
|
|
|
|
0
|
grep { $_->{name} ne $self->{name} } |
|
261
|
0
|
|
|
|
|
0
|
@{$self->{_forkref}{_labels}{$label}}; |
|
|
0
|
|
|
|
|
0
|
|
|
262
|
|
|
|
|
|
|
} |
|
263
|
|
|
|
|
|
|
} else { |
|
264
|
0
|
|
|
|
|
0
|
@{$self->{_forkref}{_labels}{$self->{label}}} = |
|
265
|
0
|
|
|
|
|
0
|
grep { $_->{name} ne $self->{name} } |
|
266
|
0
|
|
|
|
|
0
|
@{$self->{_forkref}{_labels}{$self->{label}}}; |
|
|
0
|
|
|
|
|
0
|
|
|
267
|
|
|
|
|
|
|
} |
|
268
|
|
|
|
|
|
|
} |
|
269
|
|
|
|
|
|
|
} |
|
270
|
|
|
|
|
|
|
|
|
271
|
34
|
|
|
34
|
|
272
|
use vars qw($_Calc_Runable_Fork); |
|
|
34
|
|
|
|
|
68
|
|
|
|
34
|
|
|
|
|
50461
|
|
|
272
|
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
sub _calc_runable { |
|
274
|
1158
|
|
|
1158
|
|
2798
|
my $self = shift; |
|
275
|
|
|
|
|
|
|
# @_ = objects to add as prereqs |
|
276
|
1158
|
100
|
|
|
|
4543
|
return if ($self->{_state} ne 'ready'); |
|
277
|
|
|
|
|
|
|
#use Data::Dumper; print "CR ",Dumper($self),"\n"; |
|
278
|
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
# Used by the callbacks |
|
280
|
704
|
|
|
|
|
2223
|
local $_Calc_Runable_Fork = $self->{_forkref}; |
|
281
|
|
|
|
|
|
|
sub _ranok { |
|
282
|
653
|
|
|
653
|
|
3177
|
my $procref = $_Calc_Runable_Fork->{_processes}{$_[0]}; |
|
283
|
653
|
50
|
50
|
|
|
2365
|
print " _ranok $procref->{name} State $procref->{_state}\n" if ($Debug||0)>=2; |
|
284
|
653
|
|
100
|
|
|
2073
|
return ($procref->is_done && $procref->status_ok); |
|
285
|
|
|
|
|
|
|
} |
|
286
|
|
|
|
|
|
|
sub _ranfail { |
|
287
|
604
|
|
|
604
|
|
1861
|
my $procref = $_Calc_Runable_Fork->{_processes}{$_[0]}; |
|
288
|
604
|
50
|
50
|
|
|
2462
|
print " _ranfail $procref->{name} State $procref->{_state}\n" if ($Debug||0)>=2; |
|
289
|
604
|
|
100
|
|
|
1387
|
return ($procref->is_done && !$procref->status_ok); |
|
290
|
|
|
|
|
|
|
} |
|
291
|
|
|
|
|
|
|
sub _parerr { |
|
292
|
565
|
|
|
565
|
|
2427
|
my $procref = $_Calc_Runable_Fork->{_processes}{$_[0]}; |
|
293
|
565
|
50
|
50
|
|
|
1796
|
print " _parerr $procref->{name} State $procref->{_state}\n" if ($Debug||0)>=2; |
|
294
|
565
|
|
|
|
|
1666
|
return ($procref->is_parerr); |
|
295
|
|
|
|
|
|
|
} |
|
296
|
|
|
|
|
|
|
|
|
297
|
704
|
100
|
|
|
|
1649
|
if (&{$self->{_runable_eqn}}) { |
|
|
704
|
100
|
|
|
|
28775
|
|
|
298
|
|
|
|
|
|
|
# Transition: ready -> runable |
|
299
|
258
|
50
|
|
|
|
7275
|
print " FrkProc $self->{name} $self->{_state} -> runable\n" if $Debug; |
|
300
|
258
|
|
|
|
|
2581
|
$self->{_state} = 'runable'; # No dependencies (yet) so can launch it |
|
301
|
258
|
|
|
|
|
2900
|
$self->{_forkref}{_runable}{$self->{name}} = $self; |
|
302
|
446
|
|
|
|
|
8561
|
} elsif (&{$self->{_parerr_eqn}}) { |
|
303
|
111
|
|
|
|
|
350
|
$_->unreference for values %{$self->{_after_parents}}; |
|
|
111
|
|
|
|
|
757
|
|
|
304
|
111
|
|
|
|
|
717
|
$self->parerr; |
|
305
|
|
|
|
|
|
|
} |
|
306
|
|
|
|
|
|
|
} |
|
307
|
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
##### STATE TRANSITIONS |
|
309
|
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
our $_Warned_Waitpid; |
|
311
|
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
sub poll { |
|
313
|
313
|
|
|
313
|
1
|
1105
|
my $self = shift; |
|
314
|
313
|
50
|
|
|
|
1768
|
return undef if !$self->{pid}; |
|
315
|
|
|
|
|
|
|
|
|
316
|
313
|
|
|
|
|
6476
|
my $got = waitpid($self->{pid}, WNOHANG); |
|
317
|
313
|
100
|
|
|
|
1846
|
if ($got!=0) { |
|
318
|
169
|
50
|
|
|
|
912
|
if ($got>0) { |
|
319
|
169
|
|
|
|
|
3697
|
$self->{status} = $?; # convert wait return to status |
|
320
|
|
|
|
|
|
|
} else { |
|
321
|
0
|
|
|
|
|
0
|
$self->{status} = undef; |
|
322
|
0
|
0
|
0
|
|
|
0
|
carp "%Warning: waitpid($self->{pid}) returned -1 instead of status; perhaps you're ignoring SIG{CHLD}?" |
|
323
|
|
|
|
|
|
|
if ($^W && !$_Warned_Waitpid); |
|
324
|
0
|
|
|
|
|
0
|
$_Warned_Waitpid = 1; |
|
325
|
|
|
|
|
|
|
} |
|
326
|
|
|
|
|
|
|
# Transition: running -> 'done' |
|
327
|
169
|
50
|
|
|
|
13078
|
print " FrkProc $self->{name} $self->{_state} -> done ($self->{status})\n" if $Debug; |
|
328
|
169
|
|
|
|
|
2323
|
delete $self->{_forkref}{_running}{$self->{pid}}; |
|
329
|
169
|
|
|
|
|
911
|
$self->{pid} = undef; |
|
330
|
169
|
|
|
|
|
1974
|
$self->{_state} = 'done'; |
|
331
|
169
|
|
|
|
|
1962
|
$self->{end_time} = time(); |
|
332
|
169
|
|
|
|
|
2792
|
$self->{run_on_finish}->($self, $self->{status}); |
|
333
|
|
|
|
|
|
|
# Transition children: ready -> runable |
|
334
|
169
|
|
|
|
|
2383
|
foreach my $ra (values %{$self->{_after_children}}) { |
|
|
169
|
|
|
|
|
3072
|
|
|
335
|
219
|
|
|
|
|
1775
|
$ra->_calc_runable; |
|
336
|
|
|
|
|
|
|
} |
|
337
|
169
|
|
|
|
|
636
|
$_->unreference for values %{$self->{_after_parents}}; |
|
|
169
|
|
|
|
|
2109
|
|
|
338
|
|
|
|
|
|
|
# Done |
|
339
|
169
|
|
|
|
|
1345
|
return $self; |
|
340
|
|
|
|
|
|
|
} |
|
341
|
144
|
|
|
|
|
1069
|
return undef; |
|
342
|
|
|
|
|
|
|
} |
|
343
|
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
sub kill { |
|
345
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
346
|
0
|
|
0
|
|
|
|
my $signal = shift || 9; |
|
347
|
0
|
0
|
|
|
|
|
CORE::kill($signal, $self->{pid}) if $self->{pid}; |
|
348
|
|
|
|
|
|
|
# We don't remove it's pid, we'll get a child exit that will do it |
|
349
|
|
|
|
|
|
|
} |
|
350
|
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
sub kill_tree { |
|
352
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
353
|
0
|
|
0
|
|
|
|
my $signal = shift || 9; |
|
354
|
0
|
0
|
|
|
|
|
return if !$self->{pid}; |
|
355
|
0
|
|
|
|
|
|
my @proc = (_subprocesses($self->{pid}), $self->{pid}); |
|
356
|
0
|
|
|
|
|
|
foreach my $pid (@proc) { |
|
357
|
0
|
0
|
|
|
|
|
print " Fork Kill -$signal $pid (child of $pid)\n" if $Debug; |
|
358
|
0
|
|
|
|
|
|
CORE::kill($signal, $pid); |
|
359
|
|
|
|
|
|
|
} |
|
360
|
|
|
|
|
|
|
# We don't remove it's pid, we'll get a child exit that will do it |
|
361
|
|
|
|
|
|
|
} |
|
362
|
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
sub format_time { |
|
364
|
0
|
|
|
0
|
0
|
|
my $secs = shift; |
|
365
|
0
|
|
|
|
|
|
return sprintf("%02d:%02d:%02d", int($secs/3600), int(($secs%3600)/60), $secs % 60); |
|
366
|
|
|
|
|
|
|
} |
|
367
|
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
sub format_loctime { |
|
369
|
0
|
|
|
0
|
0
|
|
my $time = shift; |
|
370
|
0
|
|
|
|
|
|
my ($sec,$min,$hour) = localtime($time); |
|
371
|
0
|
|
|
|
|
|
return sprintf("%02d:%02d:%02d", $hour, $min, $sec); |
|
372
|
|
|
|
|
|
|
} |
|
373
|
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
sub _write_tree_line { |
|
375
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
376
|
0
|
|
|
|
|
|
my $level = shift; |
|
377
|
0
|
|
|
|
|
|
my $linenum = shift; |
|
378
|
0
|
|
|
|
|
|
my $cmt = ""; |
|
379
|
0
|
0
|
|
|
|
|
if (!$linenum) { |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
380
|
0
|
|
|
|
|
|
my $state = uc $self->{_state}; |
|
381
|
0
|
0
|
0
|
|
|
|
$state .= "-ok" if $self->is_done && $self->status_ok; |
|
382
|
0
|
0
|
0
|
|
|
|
$state .= "-err" if $self->is_done && !$self->status_ok; |
|
383
|
|
|
|
|
|
|
return sprintf("%s %-27s %-8s %s\n", |
|
384
|
|
|
|
|
|
|
"--", #x$level |
|
385
|
|
|
|
|
|
|
$self->{name}, |
|
386
|
|
|
|
|
|
|
$state, # DONE-err is longest |
|
387
|
0
|
|
0
|
|
|
|
($self->{comment}||"")); |
|
388
|
|
|
|
|
|
|
} elsif ($linenum == 1) { |
|
389
|
0
|
0
|
|
|
|
|
if ($self->{start_time}) { |
|
390
|
0
|
|
|
|
|
|
$cmt .= "Start ".format_loctime($self->{start_time}); |
|
391
|
0
|
0
|
|
|
|
|
if ($self->{end_time}) { |
|
392
|
0
|
|
|
|
|
|
$cmt .= ", End ".format_loctime($self->{end_time}); |
|
393
|
0
|
|
|
|
|
|
$cmt .= ", Took ".format_time(($self->{end_time}-$self->{start_time})); |
|
394
|
0
|
|
|
|
|
|
$cmt .= ", Pid ".$self->{pid_last_run}; |
|
395
|
|
|
|
|
|
|
} |
|
396
|
|
|
|
|
|
|
} |
|
397
|
|
|
|
|
|
|
} elsif ($linenum == 2) { |
|
398
|
0
|
0
|
|
|
|
|
$cmt .= "Runaft = ".$self->{_runafter_text} if defined $self->{_runafter_text}; |
|
399
|
|
|
|
|
|
|
} elsif ($linenum == 3) { |
|
400
|
0
|
0
|
|
|
|
|
$cmt .= "RunEqn = ".$self->{_runable_eqn_text} if defined $self->{_runable_eqn_text} ; |
|
401
|
|
|
|
|
|
|
} elsif ($linenum == 4) { |
|
402
|
0
|
0
|
|
|
|
|
$cmt .= "ErrEqn = ".$self->{_parerr_eqn_text} if defined $self->{_parerr_eqn_text} ; |
|
403
|
|
|
|
|
|
|
} |
|
404
|
0
|
|
|
|
|
|
return sprintf("%s %-27s %-8s %s\n", |
|
405
|
|
|
|
|
|
|
" ", #x$level |
|
406
|
|
|
|
|
|
|
"", |
|
407
|
|
|
|
|
|
|
"", |
|
408
|
|
|
|
|
|
|
$cmt); |
|
409
|
|
|
|
|
|
|
} |
|
410
|
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
sub _subprocesses { |
|
412
|
0
|
|
0
|
0
|
|
|
my $parent = shift || $$; |
|
413
|
|
|
|
|
|
|
# All pids under the given parent |
|
414
|
|
|
|
|
|
|
# Used by testing module |
|
415
|
|
|
|
|
|
|
# Same function in Schedule::Load::_subprocesses |
|
416
|
0
|
|
|
|
|
|
my $pt = new Proc::ProcessTable( 'cache_ttys' => 1); |
|
417
|
0
|
|
|
|
|
|
my %parent_pids; |
|
418
|
0
|
|
|
|
|
|
foreach my $p (@{$pt->table}) { |
|
|
0
|
|
|
|
|
|
|
|
419
|
0
|
|
|
|
|
|
$parent_pids{$p->pid} = $p->ppid; |
|
420
|
|
|
|
|
|
|
} |
|
421
|
0
|
|
|
|
|
|
my @out; |
|
422
|
0
|
|
|
|
|
|
my @search = ($parent); |
|
423
|
0
|
|
|
|
|
|
while ($#search > -1) { |
|
424
|
0
|
|
|
|
|
|
my $pid = shift @search; |
|
425
|
0
|
0
|
|
|
|
|
push @out, $pid if $pid ne $parent; |
|
426
|
0
|
|
|
|
|
|
foreach (keys %parent_pids) { |
|
427
|
0
|
0
|
|
|
|
|
push @search, $_ if $parent_pids{$_} == $pid; |
|
428
|
|
|
|
|
|
|
} |
|
429
|
|
|
|
|
|
|
} |
|
430
|
0
|
|
|
|
|
|
return @out; |
|
431
|
|
|
|
|
|
|
} |
|
432
|
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
###################################################################### |
|
434
|
|
|
|
|
|
|
#### Package return |
|
435
|
|
|
|
|
|
|
1; |
|
436
|
|
|
|
|
|
|
=pod |
|
437
|
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
=head1 NAME |
|
439
|
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
Parallel::Forker::Process - Single parallel fork process object |
|
441
|
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
443
|
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
$obj->run; |
|
445
|
|
|
|
|
|
|
$obj->poll; |
|
446
|
|
|
|
|
|
|
$obj->kill(<"SIGNAL">); |
|
447
|
|
|
|
|
|
|
$obj->kill_tree(<"SIGNAL">); |
|
448
|
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
450
|
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
Manage a single process under the control of Parallel::Forker. |
|
452
|
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
Processes are created by calling a Parallel::Forker object's schedule |
|
454
|
|
|
|
|
|
|
method, and retrieved by various methods in that class. |
|
455
|
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
Processes transition over 6 states. They begin in idle state, and are |
|
457
|
|
|
|
|
|
|
transitioned by the user into ready state. As their dependencies complete, |
|
458
|
|
|
|
|
|
|
Parallel::Forker transitions them to the runable state. As the |
|
459
|
|
|
|
|
|
|
Parallel::Forker object's C limit permits, they transition to the |
|
460
|
|
|
|
|
|
|
running state, and get executed. On completion, they transition to the |
|
461
|
|
|
|
|
|
|
done state. If a process depends on another process, and that other |
|
462
|
|
|
|
|
|
|
process fails, the dependant process transitions to the parerr (parent |
|
463
|
|
|
|
|
|
|
error) state, and is never run. |
|
464
|
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
=head1 METHODS |
|
466
|
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
=over 4 |
|
468
|
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
=item forkref |
|
470
|
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
Return the parent Parallel::Forker object this process belongs to. |
|
472
|
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
=item is_done |
|
474
|
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
Returns true if the process is in the done state. |
|
476
|
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
=item is_idle |
|
478
|
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
Returns true if the process is in the idle state. |
|
480
|
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
=item is_parerr |
|
482
|
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
Returns true if the process is in the parent error state. |
|
484
|
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
=item is_ready |
|
486
|
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
Returns true if the process is in the ready state. |
|
488
|
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
=item is_reapable |
|
490
|
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
Returns true if the process is reapable (->reap may be called on it). |
|
492
|
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
=item is_runable |
|
494
|
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
Returns true if the process is in the runable state. |
|
496
|
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
=item is_running |
|
498
|
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
Returns true if the process is in the running state. |
|
500
|
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
=item kill() |
|
502
|
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
Send the specified signal to the process if it is running. If no signal is |
|
504
|
|
|
|
|
|
|
specified, send a SIGKILL (9). |
|
505
|
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
=item kill_tree() |
|
507
|
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
Send the specified signal to the process (and its subchildren) if it is |
|
509
|
|
|
|
|
|
|
running. If no signal is specified, send a SIGKILL (9). |
|
510
|
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
=item kill_tree_all() |
|
512
|
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
Send a signal to this child (and its subchildren) if it is running. If no |
|
514
|
|
|
|
|
|
|
signal is specified, send a SIGKILL (9). |
|
515
|
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
=item label |
|
517
|
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
Return the label of the process, if any, else undef. |
|
519
|
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
=item name |
|
521
|
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
Return the name of the process. |
|
523
|
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
=item pid |
|
525
|
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
Return the process ID if this job is running, else undef. |
|
527
|
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
=item poll |
|
529
|
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
Check the process for activity, invoking callbacks if needed. |
|
531
|
|
|
|
|
|
|
Generally Parallel::Forker's object method C is used instead. |
|
532
|
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
=item ready |
|
534
|
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
Mark this process as being ready for execution when all C's are |
|
536
|
|
|
|
|
|
|
ready and CPU resources permit. When that occurs, run will be called on |
|
537
|
|
|
|
|
|
|
the process automatically. |
|
538
|
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
=item reap |
|
540
|
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
When the process has no other processes waiting for it, and the process is |
|
542
|
|
|
|
|
|
|
is_done or is_parerr, remove the data structures for it. This reclaims |
|
543
|
|
|
|
|
|
|
memory for when a large number of processes are being created, run, and |
|
544
|
|
|
|
|
|
|
destroyed. |
|
545
|
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
=item run |
|
547
|
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
Unconditionally move the process to the "running" state and start it. |
|
549
|
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
=item run_after |
|
551
|
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
Add a new (or list of) processes that must be completed before this process |
|
553
|
|
|
|
|
|
|
can be runnable. You may pass a process object (from schedule), a process |
|
554
|
|
|
|
|
|
|
name, or a process label. You may use "|" or "&" in a string to run this |
|
555
|
|
|
|
|
|
|
process after ANY processes exit, or after ALL exit (the default.) |
|
556
|
|
|
|
|
|
|
! in front of a process name indicates to run if that process fails with |
|
557
|
|
|
|
|
|
|
bad exit status. ^ in front of a process indicates to run if that process |
|
558
|
|
|
|
|
|
|
succeeds OR fails. |
|
559
|
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
=item state |
|
561
|
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
Returns the name of the current state, 'idle', 'ready', 'runable', |
|
563
|
|
|
|
|
|
|
'running', 'done' or 'parerr'. For forward compatibility, use the is_idle |
|
564
|
|
|
|
|
|
|
etc. methods instead of comparing this accessor's value to a constant |
|
565
|
|
|
|
|
|
|
string. |
|
566
|
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
=item status |
|
568
|
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
Return the exit status of this process if it has completed. The exit |
|
570
|
|
|
|
|
|
|
status will only be correct if a CHLD signal handler is installed, |
|
571
|
|
|
|
|
|
|
otherwise it may be undef. |
|
572
|
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
=item status_ok |
|
574
|
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
Return true if the exit status of this process was zero. Return false if |
|
576
|
|
|
|
|
|
|
not ok, or if the status has not been determined, or if the status was |
|
577
|
|
|
|
|
|
|
undef. |
|
578
|
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
=back |
|
580
|
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
=head1 DISTRIBUTION |
|
582
|
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
The latest version is available from CPAN and from |
|
584
|
|
|
|
|
|
|
L. |
|
585
|
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
Copyright 2002-2020 by Wilson Snyder. This package is free software; you |
|
587
|
|
|
|
|
|
|
can redistribute it and/or modify it under the terms of either the GNU |
|
588
|
|
|
|
|
|
|
Lesser General Public License Version 3 or the Perl Artistic License |
|
589
|
|
|
|
|
|
|
Version 2.0. |
|
590
|
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
=head1 AUTHORS |
|
592
|
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
Wilson Snyder |
|
594
|
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
596
|
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
L |
|
598
|
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
=cut |
|
600
|
|
|
|
|
|
|
###################################################################### |