line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Time::Out ; |
2
|
|
|
|
|
|
|
@ISA = qw(Exporter) ; |
3
|
|
|
|
|
|
|
@EXPORT_OK = qw(timeout) ; |
4
|
|
|
|
|
|
|
|
5
|
3
|
|
|
3
|
|
31030
|
use strict ; |
|
3
|
|
|
|
|
8
|
|
|
3
|
|
|
|
|
125
|
|
6
|
3
|
|
|
3
|
|
15
|
use Exporter ; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
135
|
|
7
|
3
|
|
|
3
|
|
19
|
use Carp ; |
|
3
|
|
|
|
|
9
|
|
|
3
|
|
|
|
|
355
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
BEGIN { |
11
|
3
|
50
|
|
3
|
|
45
|
if (Time::HiRes->can('alarm')){ |
12
|
0
|
|
|
|
|
0
|
Time::HiRes->import('alarm') ; |
13
|
|
|
|
|
|
|
} |
14
|
3
|
50
|
|
|
|
1470
|
if (Time::HiRes->can('time')){ |
15
|
0
|
|
|
|
|
0
|
Time::HiRes->import('time') ; |
16
|
|
|
|
|
|
|
} |
17
|
|
|
|
|
|
|
} |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
$Time::Out::VERSION = '0.11' ; |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
sub timeout($@){ |
24
|
17
|
|
|
17
|
0
|
14143
|
my $secs = shift ; |
25
|
17
|
100
|
|
|
|
382
|
carp("Timeout value evaluates to 0: no timeout will be set") if ! $secs ; |
26
|
17
|
|
|
|
|
237
|
my $code = pop ; |
27
|
17
|
50
|
33
|
|
|
123
|
usage() unless ((defined($code))&&(UNIVERSAL::isa($code, 'CODE'))) ; |
28
|
17
|
|
|
|
|
33
|
my @other_args = @_ ; |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
# Disable any pending alarms. |
31
|
17
|
|
|
|
|
91
|
my $prev_alarm = alarm(0) ; |
32
|
17
|
|
|
|
|
47
|
my $prev_time = time() ; |
33
|
17
|
|
|
|
|
27
|
my $dollar_at = undef ; |
34
|
17
|
|
|
|
|
22
|
my @ret = () ; |
35
|
|
|
|
|
|
|
{ |
36
|
|
|
|
|
|
|
# Disable alarm to prevent possible race condition between end of eval and execution of alarm(0) after eval. |
37
|
17
|
|
|
0
|
|
22
|
local $SIG{ALRM} = sub {} ; |
|
17
|
|
|
|
|
287
|
|
|
0
|
|
|
|
|
0
|
|
38
|
17
|
|
|
|
|
32
|
@ret = eval { |
39
|
17
|
|
|
9
|
|
202
|
local $SIG{ALRM} = sub { die $code } ; |
|
9
|
|
|
|
|
3000454
|
|
40
|
17
|
100
|
100
|
|
|
73
|
if (($prev_alarm)&&($prev_alarm < $secs)){ |
41
|
|
|
|
|
|
|
# A shorter alarm was pending, let's use it instead. |
42
|
1
|
|
|
|
|
7
|
alarm($prev_alarm) ; |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
else { |
45
|
16
|
|
|
|
|
82
|
alarm($secs) ; |
46
|
|
|
|
|
|
|
} |
47
|
17
|
|
|
|
|
118
|
my @ret = $code->(@other_args) ; |
48
|
11
|
|
|
|
|
14001697
|
alarm(0) ; |
49
|
5
|
|
|
|
|
80
|
@ret ; |
50
|
|
|
|
|
|
|
} ; |
51
|
17
|
|
|
|
|
174
|
alarm(0) ; |
52
|
17
|
|
|
|
|
202
|
$dollar_at = $@ ; |
53
|
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
|
55
|
17
|
|
|
|
|
43
|
my $new_time = time() ; |
56
|
17
|
|
|
|
|
39
|
my $new_alarm = $prev_alarm - ($new_time - $prev_time) ; |
57
|
17
|
100
|
|
|
|
99
|
if ($new_alarm > 0){ |
|
|
100
|
|
|
|
|
|
58
|
|
|
|
|
|
|
# Rearm old alarm with remaining time. |
59
|
2
|
|
|
|
|
13
|
alarm($new_alarm) ; |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
elsif ($prev_alarm){ |
62
|
|
|
|
|
|
|
# Old alarm has already expired. |
63
|
1
|
|
|
|
|
55
|
kill 'ALRM', $$ ; |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
|
66
|
16
|
100
|
|
|
|
54
|
if ($dollar_at){ |
67
|
11
|
100
|
100
|
|
|
101
|
if ((ref($dollar_at))&&($dollar_at eq $code)){ |
68
|
8
|
|
|
|
|
27
|
$@ = "timeout" ; |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
else { |
71
|
3
|
100
|
|
|
|
5
|
if (! ref($dollar_at)){ |
72
|
2
|
|
|
|
|
5
|
chomp($dollar_at) ; |
73
|
2
|
|
|
|
|
19
|
die("$dollar_at\n") ; |
74
|
|
|
|
|
|
|
} |
75
|
|
|
|
|
|
|
else { |
76
|
1
|
|
|
|
|
76
|
croak $dollar_at ; |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
} |
80
|
|
|
|
|
|
|
|
81
|
13
|
50
|
|
|
|
87
|
return wantarray ? @ret : $ret[0] ; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
sub usage { |
86
|
0
|
|
|
0
|
0
|
|
croak("Usage: timeout \$nb_secs => sub {\n #code\n} ;\n") ; |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
1 ; |