Re: [mp2] threaded applications inside of mod_perl

[prev] [thread] [next] [Date index for 2005/02/04]

From: Stas Bekman
Subject: Re: [mp2] threaded applications inside of mod_perl
Date: 18:41 on 04 Feb 2005
Stas Bekman wrote:
> Stas Bekman wrote:
> 
>> Thanks for the details. I can now reproduce the segfault. I'll post 
>> again when this is fixed.
> 
> 
> I've traced it down to a perl-core issue. I'm submitting a report to p5p 
> and I've CC'ed you, so you can stay in the loop.
> 
> Meanwhile, there are two workarounds:

In fact just using:

  SetHandler modperl

and starting your script with:

my $r = shift;
tie *STDOUT, $r;

is sufficient. Below you will find all the workarounds that I've found 
working at the moment (added as a test to the mp2 test suite):

use strict;
use warnings FATAL => 'all';

#
# there is a problem when STDOUT is internally opened to an
# Apache::PerlIO layer is cloned on a new thread start. PerlIO_clone
# in perl_clone() is called too early, before PL_defstash is
# cloned. As PerlIO_clone calls PerlIOApache_getarg, which calls
# gv_fetchpv via sv_setref_pv and boom the segfault happens.
#
# at the moment we should either not use an internally opened to
# :Apache streams, so the config must be:
#
# SetHandler modperl
#
# and then either use $r->print("foo") or tie *STDOUT, $r + print "foo"
#
# or close and re-open STDOUT to :Apache *after* the thread was spawned
#
# the above discussion equally applies to STDIN
#
# XXX: ->join calls leak under registry, this doesn't happen in the
# non-registry tests.

use threads;

my $r = shift;
$r->print("Content-type: text/plain\n\n");

{
     # now we can use $r->print API:
     my $thr = threads->new(
         sub {
             my $id = shift;
             $r->print("thread $id\n");
             return 1;
         }, 1);
     # $thr->join; # XXX: leaks scalar
}

{
     # close and re-open STDOUT to :Apache *after* the thread was
     # spawned
     my $thr = threads->new(
         sub {
             my $id = shift;
             close STDOUT;
             open STDOUT, ">:Apache", $r
                 or die "can't open STDOUT via :Apache layer : $!";
             print "thread $id\n";
             return 1;
         }, 2);
     # $thr->join; # XXX: leaks scalar
}

{
     # tie STDOUT to $r *after* the ithread was started has
     # happened, in which case we can use print
     my $thr = threads->new(
         sub {
             my $id = shift;
             tie *STDOUT, $r;
             print "thread $id\n";
             return 1;
         }, 3);
     # $thr->join; # XXX: leaks scalar
}

{
     # tie STDOUT to $r before the ithread was started has
     # happened, in which case we can use print
     tie *STDOUT, $r;
     my $thr = threads->new(
         sub {
             my $id = shift;
             print "thread $id\n";
             return 1;
         }, 4);
     # $thr->join; # XXX: leaks scalar
}

print "parent";




        -- 
        __________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@xxxxxx.xxx http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

(message missing)

[mp2] threaded applications inside of mod_perl
bob-modperl 03:15 on 03 Feb 2005

Re: [mp2] threaded applications inside of mod_perl
Stas Bekman 18:41 on 04 Feb 2005

Generated at 11:21 on 20 Feb 2005 by mariachi v0.52