The attached patches fix this bug. Thank to Dean Arnold for the suggestion to use a PL_ function pointer.
Jerry D. Hedden wrote:
> I'm trying to come up with a fix for the bug related to
> storing shared objects inside of shared structures. The bug
> is that when any proxy objects for the shared object are
> destroyed, the object's DESTROY routine is called even
> thought the object itself should not yet be destroyed.
>
> The following elicits the bug:
> -----
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> use threads;
> use threads::shared;
>
> package Jar; {
> my @jar :shared;
>
> sub new {
> bless(&threads::shared::share({}), shift);
> }
>
> sub store {
> my ($self, $cookie) = @_;
> push(@jar, $cookie);
> print("JAR : Cookie stored\n");
> return $jar[-1]; # BUG: The cookie is destroyed here
> }
> }
>
> package Cookie; {
> my $destruction_count = 0;
>
> sub new {
> bless(&threads::shared::share({}), shift);
> }
>
> sub DESTROY {
> $destruction_count++;
> print("COOKIE: destruction count = $destruction_count\n");
> }
> }
>
> package main;
>
> MAIN:
> {
> my $jar = Jar->new();
> my $cookie = Cookie->new();
>
> print("MAIN : Storing cookie\n");
> $jar->store($cookie);
>
> print("\nMAIN : Cookie should not have been destroyed yet\n");
>
> print("\nMAIN : Exiting scope\n")
> }
>
> print("\nDONE\n");
> -----
> The above outputs:
> MAIN : Storing cookie
> JAR : Cookie stored
> COOKIE: destruction count = 1
>
> MAIN : Cookie should not have been destroyed yet
>
> MAIN : Exiting scope
> COOKIE: destruction count = 2
>
> DONE
>
> which shows that DESTROY is called twice - the first time by
> the destruction of a proxy object.
>
> I am attempting to fix this bug by first providing a call in
> threads::shared (ext/threads/shared/shared.xs) to report on
> whether or not a shared object should be destroyed: If the
> ref is shared, and its refcnt is greater than one, then it
> should NOT be destroyed.
blead.patch
Description: Binary data
shared.patch
Description: Binary data
