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__ |