| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Parallel::Workers::Shared; |
|
2
|
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
8
|
use warnings; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
36
|
|
|
4
|
1
|
|
|
1
|
|
6
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
14604
|
|
|
5
|
1
|
|
|
1
|
|
21
|
use Carp; |
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
127
|
|
|
6
|
1
|
|
|
|
|
126
|
use Scalar::Util qw(blessed dualvar isweak readonly refaddr reftype tainted |
|
7
|
1
|
|
|
1
|
|
7
|
weaken isvstring looks_like_number set_prototype); |
|
|
1
|
|
|
|
|
2
|
|
|
8
|
1
|
|
|
1
|
|
184
|
use threads 1.39; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
use threads::shared; |
|
10
|
|
|
|
|
|
|
use Thread::Queue; |
|
11
|
|
|
|
|
|
|
use Data::Dumper; |
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
our (@ISA, @EXPORT, @EXPORT_OK); |
|
15
|
|
|
|
|
|
|
@ISA = qw(Exporter); |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
@EXPORT = qw(shared_hash_set shared_share); |
|
18
|
|
|
|
|
|
|
@EXPORT_OK = (); |
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
# Adds fields to a shared object |
|
21
|
|
|
|
|
|
|
sub shared_hash_set{ |
|
22
|
|
|
|
|
|
|
my ($this, $tag, $value) = @_; |
|
23
|
|
|
|
|
|
|
share ($this) unless is_shared($this); |
|
24
|
|
|
|
|
|
|
lock($this); |
|
25
|
|
|
|
|
|
|
$this->{$tag} = shared_share($value); |
|
26
|
|
|
|
|
|
|
} |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
# Make a thread-shared version of a complex data structure or object |
|
29
|
|
|
|
|
|
|
sub shared_share{ |
|
30
|
|
|
|
|
|
|
my $in = shift; |
|
31
|
|
|
|
|
|
|
# If already thread-shared, then just return the input |
|
32
|
|
|
|
|
|
|
return ($in) if (is_shared($in)); |
|
33
|
|
|
|
|
|
|
# print "shared_share( ".ref($in).")\n"; |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# Make copies of array, hash and scalar refs |
|
36
|
|
|
|
|
|
|
my $out; |
|
37
|
|
|
|
|
|
|
if (my $ref_type = reftype($in)) { |
|
38
|
|
|
|
|
|
|
# Copy an array ref |
|
39
|
|
|
|
|
|
|
if ($ref_type eq 'ARRAY') { |
|
40
|
|
|
|
|
|
|
# Make empty shared array ref |
|
41
|
|
|
|
|
|
|
$out = &share([]); |
|
42
|
|
|
|
|
|
|
# Recursively copy and add contents |
|
43
|
|
|
|
|
|
|
foreach my $val (@$in) { |
|
44
|
|
|
|
|
|
|
push(@$out, shared_share($val)); |
|
45
|
|
|
|
|
|
|
} |
|
46
|
|
|
|
|
|
|
} |
|
47
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
# Copy a hash ref |
|
49
|
|
|
|
|
|
|
elsif ($ref_type eq 'HASH') { |
|
50
|
|
|
|
|
|
|
# Make empty shared hash ref |
|
51
|
|
|
|
|
|
|
$out = &share({}); |
|
52
|
|
|
|
|
|
|
# Recursively copy and add contents |
|
53
|
|
|
|
|
|
|
foreach my $key (keys(%{$in})) { |
|
54
|
|
|
|
|
|
|
$out->{$key} = shared_share($in->{$key}); |
|
55
|
|
|
|
|
|
|
} |
|
56
|
|
|
|
|
|
|
} |
|
57
|
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
# Copy a scalar ref |
|
59
|
|
|
|
|
|
|
elsif ($ref_type eq 'SCALAR') { |
|
60
|
|
|
|
|
|
|
$out = \do{ my $scalar = $$in; }; |
|
61
|
|
|
|
|
|
|
share($out); |
|
62
|
|
|
|
|
|
|
} |
|
63
|
|
|
|
|
|
|
} |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
# If copy created above ... |
|
66
|
|
|
|
|
|
|
if ($out) { |
|
67
|
|
|
|
|
|
|
# Clone READONLY flag |
|
68
|
|
|
|
|
|
|
if (Internals::SvREADONLY($in)) { |
|
69
|
|
|
|
|
|
|
Internals::SvREADONLY($out, 1); |
|
70
|
|
|
|
|
|
|
} |
|
71
|
|
|
|
|
|
|
# Make blessed copy, if applicable |
|
72
|
|
|
|
|
|
|
if (my $class = blessed($in)) { |
|
73
|
|
|
|
|
|
|
bless($out, $class); |
|
74
|
|
|
|
|
|
|
} |
|
75
|
|
|
|
|
|
|
# Return copy |
|
76
|
|
|
|
|
|
|
return ($out); |
|
77
|
|
|
|
|
|
|
} |
|
78
|
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
# Just return anything else |
|
80
|
|
|
|
|
|
|
# NOTE: This will generate an error if we're thread-sharing, |
|
81
|
|
|
|
|
|
|
# and $in is not an ordinary scalar. |
|
82
|
|
|
|
|
|
|
return ($in); |
|
83
|
|
|
|
|
|
|
} |
|
84
|
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
1; # Magic true value required at end of module |
|
87
|
|
|
|
|
|
|
__END__ |