Re: difference between PerlSetEnv and <Perl>$ENV{}=</Perl> ?

Charlie Katz <[email protected]>
Newsgroups gmane.comp.apache.mod-perl
Message-ID <CAC1kbLApxgaayiWbDVf+z9jz-f-jL1o9OL6oBkajSS+zrxPYqQ@mail.gmail.com>
Thanks for the detailed explanation.  I guess the explanation for the
behavior I see is that the C library called through Perl only has access to
the process global %ENV, and not to the particular $r->subprocess_env data
for the request through which it was called.

On Tue, Mar 27, 2012 at 1:53 PM, Torsten Förtsch
<[email protected]>wrote:

> On Tuesday, 27 March 2012 12:48:01 Charlie Katz wrote:
> > Still, can someone explain why
> >
> >    PerlSetEnv  ENV_VAR /my/value
> >
> > has different effects than
> >
> >    <Perl>
> >    $ENV{ENV_VAR} = '/my/value';
> >    </Perl>
> >
> > ?
>
> The source of the problem is that apache 2 is in general multithreaded.
> Thus,
> one request may set $ENV{var}=1 while the other may $ENV{var}=2 at the same
> time. The environment is a process global variable.
>
> To deal with the problem apache invented $r->subprocess_env, a table
> similar
> to the process environment but request specific. Then if there is a need to
> spawn off a new process and it is done via the apache API that table is
> copied
> to the process environment in the child process. For mod_cgi that solves
> the
> problem.
>
> Perl itself adds another layer to the problem because at least some
> versions
> do not serialize access to the environment. So in principle it may even
> cause
> segfaults if 2 threads are trying to modify %ENV at the same time.
>
> When modperl was ported to apache 2 it was decided to map %ENV to
> $r->subprocess_env to prevent trouble.
>
> So, with the current implementation, if there is a current request %ENV
> maps
> to its subprocess_env table. Otherwise Perl's original functions are called
> and thus modify the process global environment, see modperl_env.c
>
> If you modify %ENV in a <Perl> block there is obviously no request since
> the
> code is executed at server startup. PerlSetEnv on the other hand is
> executed
> as soon as possible in the request cycle. At that time there is a current
> request and hence $r->subprocess_env is modified.
>
> There is another way to modify the environment, SetEnv. The difference
> between
> PerlSetEnv and SetEnv is the point within the request cycle when it is
> executed. As said before PerlSetEnv is done first thing. Apache's SetEnv is
> there to set environment variables for CGI scripts and other normal
> handlers.
> For those it is sufficient to populate subprocess_env just before the
> response
> handler is called. So, SetEnv lives in the fixup phase.
>
> Since I am not the author of the code I don't know for sure all of the
> above.
> But I think over time I have got quite a bit of understanding of the
> problem
> from reading the code. Of course, one could ask what happens in a
> multithreaded MPM when 2 PerlProcessConnectionHandlers simultaneously try
> to
> modify %ENV. I don't know. Maybe it segfaults since there is no $r in this
> situation.
>
> Would be good if someone could at least setup a test scenario for this
> case.
>
> Torsten Förtsch
>
> --
> Need professional modperl support? Hire me! (http://foertsch.name)
>
> Like fantasy? http://kabatinte.net
>
>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.