I wanted to build an awesome place for people to discuss module specific issues, but I don't have any more time for this, and there are much better places to discuss Perl-related issues. I'd recommend asking your question on Stack Overflow or on Perl Monks.
If you are looking for a Perl tutorial or Perl-related news, I hope these links will serve you well.
Posted on 2007-10-27 09:17:33-07 by buchet
Problem with shared objects
This issue was originally posted under the subject Object::InsideOut. The following modified example from jdhedden should illustrate the problem:
#!/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 ); return $jar[-1]; } sub consume { pop(@jar); } } package Cookie; { sub new { my $self = bless( &threads::shared::share( {} ), shift ); $self->{contains} = 'chocolate'; return $self; } # explicit destructor like OIO objects used to have sub DESTROY { delete shift->{contains}; } } package main; MAIN: { my $jar = Jar->new(); my $cookie = Cookie->new(); print( "\nI like cookies with ", $cookie->{contains} ); $jar->store($cookie); print("\n...but the jar eats the chocolate out ot my cookie.") unless ( $jar->consume()->{contains} ); } print("\nDONE\n");
I believe that this happens during the copying of the object into the global stash inside of shared.xs.
STATIC void S_get_RV(pTHX_ SV *sv, SV *ssv) { ... ... if (SvOBJECT(sobj)) { /* Add any new old blessing */ STRLEN len; char* stash_ptr = SvPV((SV*) SvSTASH(sobj), len); HV* stash = gv_stashpvn(stash_ptr, len, TRUE); SvOBJECT_on(obj); SvSTASH_set(obj, (HV*)SvREFCNT_inc(stash)); } }
I have no experience with xs code, so I'm not sure, but it looks to me that only a thin copy of the object was done, not a deep as needed.
Direct Responses: 6360 | Write a response
Posted on 2007-10-29 15:18:03-07 by jdhedden in response to 6344
Re: Problem with shared objects
> I believe that this happens during the copying of the object
> into the global stash inside of shared.xs. I have no
> experience with xs code, so I'm not sure, but it looks to me
> that only a thin copy of the object was done, not a deep as
> needed.

The comments in the XS file explain how threads::shared work:
/* * Shared variables are implemented by a scheme similar to tieing. * Each thread has a proxy SV with attached magic -- "private SVs" -- * which all point to a single SV in a separate shared interpreter * (PL_sharedsv_space) -- "shared SVs". * * The shared SV holds the variable's true values, and its state is * copied between the shared and private SVs with the usual * mg_get()/mg_set() arrangement. * * ...
The problem with storing shared objects in shared structures involves the destruction of the 'proxy SVs': When the proxy SV is destroyed, the object's DESTROY subroutine is called even though the actual object is not being destroyed.

Here's my ignorant guess at what a solution to this might entail:
1. Modifications to the interpreter to not call DESTROY for proxy SVs.
2. Tracking of the proxy SVs and modifications to the interpreter to call DESTROY when there are no more proxy SVs for a shared object.
Direct Responses: 6420 | Write a response
Posted on 2007-11-08 16:02:31-08 by jdhedden in response to 6360
Re: Problem with shared objects
I was able to come up with a fix to the Perl interpreter for this.

If you want to store shared objects inside other shared structures, you'll need to get Perl 5.10.0 (either build the lastest snapshot yourself, or wait for an official release), and then upgrade threads::shared to version 1.15 or later.
Direct Responses: Write a response