1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
package FusionInventory::Agent::Threads;
use strict;
use warnings;
use threads;
use threads::shared;
use base 'Exporter';
no warnings 'redefine';
use Scalar::Util qw(refaddr reftype);
our @EXPORT = qw(shared_clone);
# version 1.21, appearing with perl 5.10.1
sub shared_clone {
my ($item, $cloned) = @_;
# Just return the item if:
# 1. Not a ref;
# 2. Already shared; or
# 3. Not running 'threads'.
return $item
if (! ref($item) || threads::shared::_id($item) || ! $threads::threads);
# initialize clone checking hash if needed
$cloned = {} unless $cloned;
# Check for previously cloned references
# (this takes care of circular refs as well)
my $addr = refaddr($item);
if (exists($cloned->{$addr})) {
# Return the already existing clone
return $cloned->{$addr};
}
# Make copies of array, hash and scalar refs
my $copy;
my $ref_type = reftype($item);
# Copy an array ref
if ($ref_type eq 'ARRAY') {
# Make empty shared array ref
$copy = &share([]);
# Add to clone checking hash
$cloned->{$addr} = $copy;
# Recursively copy and add contents
push(@$copy, map { shared_clone($_, $cloned) } @$item);
}
# Copy a hash ref
elsif ($ref_type eq 'HASH') {
# Make empty shared hash ref
$copy = &share({});
# Add to clone checking hash
$cloned->{$addr} = $copy;
# Recursively copy and add contents
foreach my $key (keys(%{$item})) {
$copy->{$key} = shared_clone($item->{$key}, $cloned);
}
}
# Copy a scalar ref
elsif ($ref_type eq 'SCALAR') {
$copy = \do{ my $scalar = $$item; };
share($copy);
# Add to clone checking hash
$cloned->{$addr} = $copy;
}
return $copy;
}
1;
__END__
=head1 NAME
FusionInventory::Agent::Threads - Backported threads::shared functions
=head1 DESCRIPTION
This module contains backported threads::shared functions for perl 5.8
compatibility.
=head1 FUNCTIONS
=head2 shared_clone($variable)
"shared_clone" takes a reference, and returns a shared version of its argument,
performing a deep copy on any non-shared elements. Any shared elements in the
argument are used as is (i.e., they are not cloned).
|