What I did to get worker and event working under FreeBSD 6.3,
was to eliminate the child_init handler, and at the start of
the response handler do something like

my $env;

 sub handler { # this is the response handler
        my ($r) = @_;
        if (!$env) {
        $env = DbEnv->new;
        $env->open( $envdir, Db::DB_USE_ENVIRON | Db::DB_THREAD);
                ...
       }
        ...
 }

What this means is that each thread must open the db's for itself.
The amount of data stored for each open DB connection, times
THREADS_PER_CHILD times the number of Apache children at any
given point, makes for some memory.  But

1) the separate connections help the DB package be thread-safe,
2) the first-used threads keep getting re-used in preference to
   threads not yet used.
3) if you consider each thread as more or less equivalent to a
   child process in prefork, your total memory requirement is less.

Guten abend (in meiner Zeitzone),
cmac
www.animalhead.com


On Jan 16, 2009, at 11:34 AM, Michael Ludwig wrote:

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

Reply via email to