shotgunefx has asked for the wisdom of the Perl Monks concerning the following question:

My understanding is that all copies of a mod_perl enabled apache will "share" loaded modules.

If this is the case, isn't there the possibility of one Apache::Registry script interfering with another?

Take CGI.pm for example,if you want to disable file uploads for one Apache::Registry script by adding

$DISABLE_UPLOADS = 1 and then another script enables it by

$DISABLE_UPLOADS = 0 , aren't they modifying the same variable?

If so, doesn't that mean that a script that disables it at some point could interfere with another or subsequent running Apache::Registry script that enables, correct?

Am I confused about how this is working behind the scenes? I have had a hard time tracking down the answer to this but maybe I'm just looking in the wrong places. ;)

Can someone enlighten me?

Thanks
-Lee

Replies are listed 'Best First'.
Re (tilly) 1: Package Globals and mod_perl
by tilly (Archbishop) on May 16, 2001 at 20:17 UTC
    Two details.

    First of all each script is created in its own namespace. So one script's package globals should not interfere with anther if you don't influence variables in packages.

    But if, as above, you influence a variable in another package, then you can get conflicts. To make this not a problem you can use local. As in:

    local $CGI::DISABLE_UPLOADS = 1;
    Then when your script runs it will properly localize its effects.
Re: Package Globals and mod_perl
by mr.nick (Chaplain) on May 16, 2001 at 19:24 UTC
    I just created a canned test:

    GlobalTest.pm

    package GlobalTest; $GLOBALA = 10; 1;
    gt.cgi
    #!/usr/bin/perl use GlobalTest; print "Content-type: text/plain\n\n"; print $GlobalTest::GLOBALA;
    gt2.cgi
    #!/usr/bin/perl use GlobalTest; print "Content-type: text/plain\n\n"; $GlobalTest::GLOBALA=30; print $GlobalTest::GLOBALA;
    I then ran gt2.cgi about 10 times (to make sure all my instances of apache had loaded it). When I ran gt.cgi, I got the answer of 30, not of 10.

    So, yes, package globals stick around regardless of the calling CGI when using mod_perl; at least with this scenerio.

      I don't know anything about mod_perl, so I might be wrong. But I thought mod_perl usually created one or more processes, each of which has multiple threads but a single instance of the Perl interpretter. And that these processes are restarted fromt time to time. This means that the behavior that you saw will only happen for threads that happen to share the same interpretter.

      So if you generate enough load for there to be two processes handling your requests, then the variable will only be shared within each group. Also, when the process is restarted, the previous value of the variable will not be propogated to the new process.

      Just FYI (if you care to believe me).

              - tye (but my friends call me "Tye")
        That is correct: each process or instance of the apache server runs one instance of mod_perl; which as you stated, runs one copy of Perl.

        Hits against a web server can easily bounce from one instance to another without warning or control. You don't have to create "enough load" to do it: it automatically happens. My server is 99.99% idle and yet I can easily get a script to bounce from one instance to another with just hitting "reload" twice.

        That's what makes this such an annoying "feature": you don't know if the instance of mod_perl (and CGI.pm) that your script is running on has had it's globals modified by another script. Multiple scripts WILL execute under the same instance of mod_perl (as my example showed).

        A whole area of security has suddenly popped up for me. If I allow user-run mod_perl scripts; what's to stop them from modifying some globals in classes that I use? Nothing :-/

        Update: tilly is correct, using local will correct for the above problem; but it doesn't help in "default" globals. I mean, now do I have to go through and reset by hand, using local, *ALL* of the globals that a package uses? Even the one's I would not normally touch? It seems to ensure that their values are correct, I do.

        Thanks Tye.

        Apache will cycle through the various children in my experience, pretty quickly under a light load.

        The reason I noticed this is that I am writing a module derived from CGI.pm and saw weird results about every 5 hits.

        My module uses a few globals internally, I guess I'll have to do some recoding.

        Thanks.