perl-modperl mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michael Ludwig <...@as-guides.com>
Subject Re: Initializing Sleepycat::DbXml (Berkeley, Oracle) objects in startup.pl
Date Fri, 16 Jan 2009 19:34:47 GMT
Mark Hedges schrieb:
>>
>> *** glibc detected *** free(): invalid pointer: 0x084e6a14 ***
>
> If this didn't work in a response handler, I'd guess there's
> something else wrong.  That's the kind of error you get when
> you use things under threads that are not thread-safe in
> some way, I remember that sort of thing trying to use
> List::MoreUtils::natatime() under threads.  (But the rest of
> that library works.)  It's a sad state of affairs that a
> large chunk of CPAN doesn't play nice with threads, and
> there's usually not any way of knowing which library is
> causing the problem.  It might not even be the oracle
> thingy, maybe something else you're loading.

It may have been XML::LibXML, XML::LibXSLT, or - most probably - my
lack of understanding of the worker MPM and threaded Perl.

I made some progress and got it working using package-level
my-variables to cache the Berkeley handles.

Still, concurrent access quite reliably manages to produce SEGVs.
This may have something to do with with not finalizing the handles
properly.

So I think I have to use PerlChildInitHandler and PerlChildExitHandler.

I spent some time wondering why the variables I initialized in the
PerlChildInitHandler Eumel::A::child_init were undefined when
accessed from the PerlResponseHandler Eumel::B::handler, regardless
of whether they were declared with our or with my and then returned
by a function.

I thought that moving the child_init method into the same package
as the handler and having it initialize package level my-variables
or our-variables might do the trick. But it doesn't.

Looks like the variables that the PerlChildInitHandler sees are
different beasts than those the PerlResponseHandler sees, even
though they are textually identical.

Turns out under the threaded worker MPM things behave differently:

| Global variables are only global to the interpreter in which
| they are created. Other interpreters from other threads
| can't access that variable. Though it's possible to make
| existing variables shared between several threads running in
| the same process by using the function
| threads::shared::share().

http://perl.apache.org/docs/2.0/user/coding/coding.html#Shared_Variables

Should have RTFM before.

I haven't used threads to this date, nor threads::shared. Looks like
I'd have to share the Berkeley handles in order for it to *maybe*
work.

Now here's a funny one.

use threads;
use threads::shared;

our $env;

sub child_init {
     share($env); 

     $env = DbEnv->new;
     $env->open( $envdir, Db::DB_USE_ENVIRON | Db::DB_THREAD);
     print STDERR "child_init: Umgebung geoeffnet\n";
     ...
}

I never see the log message - the PerlChildInitHandler thing is
hanging. Which bizarrely doesn't stop the PerlResponseHandler, by
the way.

If I uncomment "use threads", the threads::shared stuff conveniently
turns into no-ops, and I get back the old behaviour, which is that
the PerlChildInitHandler and the PerlResponseHandler do not see the
same variables in spite of their being textually identical.

I'm at my wit's end. Any clues?

Michael Ludwig

Mime
View raw message