package Thread::Shared::Array; use threads::shared '1.02', qw/ share is_shared /; use Thread::Shared; use strict; sub TIEARRAY { my $class = shift; my $value = shift; if ( not defined $value or not is_shared $value ) { $value = &share([]); } my $self = { array => $value }; bless $self, $class; return $self; } sub FETCH { my ($self, $index) = @_; my $value = $self->{array}->[$index]; if ( ref($value) ) { $value = Thread::Shared::wrap($value); } return $value; } sub STORE { my ($self, $index, $value) = @_; $self->{array}->[$index] = Thread::Shared::make_shared($value); } sub FETCHSIZE { my $self = shift; return scalar @{$self->{array}}; } sub STORESIZE { my ($self, $count) = shift; if ( $count > $self->FETCHSIZE() ) { foreach ( $count - $self->FETCHSIZE() .. $count ) { $self->STORE($_, undef); } } elsif ( $count < $self->FETCHSIZE() ) { foreach ( 0 .. $self->FETCHSIZE() - $count - 2 ) { $self->POP(); } } } sub EXTEND { my ($self, $count) = shift; $self->STORESIZE($count); } sub EXISTS { my ($self, $index) = shift; return exists $self->{array}->[$index]; } sub DELETE { my ($self, $index) = shift; delete $self->{array}->[$index]; } sub CLEAR { my $self = shift; $self->{array} = &share([]); } sub PUSH { my $self = shift; foreach my $item ( @_ ) { push @{$self->{array}}, Thread::Shared::make_sharable($item); } return $self->FETCHSIZE(); } sub POP { my $self = shift; my $value = pop @{$self->{array}}; if ( ref($value) ) { $value = Thread::Shared::wrap($value); } return $value; } sub SHIFT { my $self = shift; my $value = shift @{$self->{array}}; if ( ref($value) ) { $value = Thread::Shared::wrap($value); } return $value; } sub UNSHIFT { my $self = shift; my $value = unshift @{$self->{array}}; if ( ref($value) ) { $value = Thread::Shared::wrap($value); } return $value; } sub SPLICE { my ($self, $offset, $length) = (shift, shift, shift); my @value = splice @{$self->{array}}, $offset, $length, @_; my $ref = Thread::Shared::wrap(\@value); return @$ref; } sub UNTIE { my $self = shift; # TODO: me! } sub DESTROY { my $self = shift; # TODO: me! } 1;