develooper Front page | perl.perl5.porters | Postings from January 2017

[perl #130649] Threads, shared memory, blessed objects fail to call->DESTROY method

Thread Previous | Thread Next
From:
James E Keenan via RT
Date:
January 26, 2017 14:28
Subject:
[perl #130649] Threads, shared memory, blessed objects fail to call->DESTROY method
Message ID:
rt-4.0.24-13191-1485440881-131.130649-15-0@perl.org
On Thu, 26 Jan 2017 12:38:49 GMT, victor.burns@bankofamerica.com wrote:
> This is a bug report for Perl from victor.burns@bankofamerica.com,
> generated with the help of perlbug 1.39 running under perl 5.12.2.
> 
> 
> -----------------------------------------------------------------
> [Please describe your issue here]
> 
> This issue is believed to exist in all 5.10.1+ Perl's and every older
> Perl as well.
> I have verified the issue in every Perl I have at my disposal from
> 5.10.1, 5.12.0, 5.22.0 and 5.24.0.
> 
> Description:
> If the last reference to an object is in thread shared memory the
> objects
> DESTROY method won't be called or highly unlikely to be called. This
> is a
> *huge* problem for applications that are OO and designed using
> composition
> of other classes (HAS-A). The last, and possibly only reference will
> be in
> Perl's thread shared memory. I think the real issue only resembles my
> description and therefore it is not perfect. I have however included a
> small script that when used and modified as the comments suggest the
> related behaviors may be observed. The actual issue is a bit more
> unpredictable.
> 
> ## PERL BUG Example
> 
> use 5.010001;
> use strict;
> use warnings;
> use threads;
> use threads::shared;
> 
> our $VERSION = 0.1;
> 
> say 'Hello World!, - Perl shared memory failure to call ->DESTROY
> detector.';
> 
> LEAKER:
> {
>   ## Using the "shared" attribute can play a role in this
>   ##  Best guess it means all references are shared.
>   my $aa :shared = bless &share({}), 'Lazy::Crazy';
>   my $bb :shared = bless &share({}), 'Lazy::Crazy';
>   my $cc :shared = &share( bless {}, 'Lazy::Crazy' );
> 
>   ## Placing an object into another makes it a sure bet its
>   ##  ->DESTROY won't be called
>   $aa->{ has_c } = $cc;
>   $bb->{ has_a } = $aa;
> 
>   ## It's strange that the order of the following assignments
>   ##  will allow the last one touched to call its ->DESTROY
>   $cc->{ label } = 'c';
>   $aa->{ label } = 'a';
>   $bb->{ label } = 'b';
> 
>   ## If I'm able to control the order these are unwrapped (destroyed)
>   ##  things start working as expected.
>   ##    How likely can I always get this right, not at all!
>   ## (uncomment and things work as expected)
> # $bb = undef;
> # $aa = undef;
> # $cc = undef;
> }
> 
> package Lazy::Crazy;
> 
> sub DESTROY
> {
>   my $self = shift;
>   printf "# %s '%s' is destroyed\n", ref $self, $self->{ label };
>   return;
> }
> 
> ## END
> 

I would like to confirm the output one is supposed to get from running this program.

Running the program as submitted (which, for convenience, I am attaching to this RT), I get:

#####
[threaded_blead] $ ./bin/perl -Ilib ~/learn/perl/p5p/130649-threads.pl
Hello World!, - Perl shared memory failure to call ->DESTROY detector.
# Lazy::Crazy 'b' is destroyed
#####

Uncommenting lines 34-36 -- the last 3 lines of the 'LEAKER' block -- and then running the program I get:

#####
[threaded_blead] $ ./bin/perl -Ilib ~/learn/perl/p5p/130649-threads.pl
Hello World!, - Perl shared memory failure to call ->DESTROY detector.
# Lazy::Crazy 'b' is destroyed
# Lazy::Crazy 'a' is destroyed
# Lazy::Crazy 'c' is destroyed
#####

Is that the output you were expecting?

Thank you very much.

-- 
James E Keenan (jkeenan@cpan.org)

---
via perlbug:  queue: perl5 status: new
https://rt.perl.org/Ticket/Display.html?id=130649

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About