Joe Schaefer wrote:
Stas Bekman <[EMAIL PROTECTED]> writes:

[...]


It seems that your global $GlobalS var contains a reference to an
Apache::Request table, but A-R object is not global, so when the scope
of the handler is exited A-R object gets destroyed, leaving $GlobalS
containting a pointer to a black hole. That black hole is req->parms
in Request.xs in libapreq.


<yack>
Yup- the request pool's cleanup hook has already come through and
reclaimed all those C data structures. Unfortunately the perl glue
isn't aware that this happened.


I think the basic assumption is that the request pool's lifetime must
be longer than any perl scalar glued to a per-request struct. Of
course, that assumption doesn't appear to be valid in this situation (a global Apache::Table object is alive, but the associated C table was
freed). Not sure what to do about it right now.
</yack>

We have exactly the same issue with APR::Pool objects created via


  my $parent_pool = APR::Pool->new();
  my $child_pool = $parent_pool->new();

if $parent_pool is destroyed first, it also eats the guts of its child, leaving $child_pool pointing to some invalid thing. The worst thing is that if some other pool gets allocated at the same pointer where child_pool point, it will be destroyed!

Moreover, every time you say:

my $parent2 = $child_pool->parent_get;

you can't destroy $parent2, because it will nuke the guts of the parent and all the children. Therefore you can't just wrap and IV pointer into an SV and hand it to the perl side.

Currently the solution that almost works is to introduce an internal reference counting, by incrementing the reference counting every time a new perl variable pointing to the pool is created, and decrementing when it's attempted to be destroyed. Only when the reference count reaches 0 we can destroy the actual pool. This reference counting is stored inside the C pool struct itself, via user data API.

It's almost working. There is at least one problem with this approach that I forgot what it was, but I have a test that demonstrates it somewhere. The solution that I'm thinking to implement involves storing a real SV in the pool's user data and use Perl's reference counting.

I think the same approach can be taken by A-R. Once I'll polish the solution with APR::Pool, we can apply it to A-R. In any case I've provided Marc with a workaround which should prevent segfaults, so there is no rush to fix it if you are busy with more urgent things.

ALso, Marc, I'd suggest to rethink your coding techniques. Instead of using globals you should probably encapsulate all the data that you want to pass around into a single object and and pass it around, or using a Singleton object. Globals are not the best way to go in majority of cases.

__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


-- Reporting bugs: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html



Reply via email to