Loading ...
Sorry, an error occurred while loading the content.

61086Re: Apache::PerlRun - Constant subroutine redefined

Expand Messages
  • David Radunz
    Oct 3 11:30 PM
      Also forgot to mention, this is running:

      mod_perl 1.29
      perl 5.8.4
      apache 1.3.27

      and ..

      SunOS *** 5.9 Generic_112234-08 i86pc i386 i86pc

      Cheers


      On Mon, 2004-10-04 at 16:15, David Radunz wrote:
      > Hi All,
      >
      > I have looked high and low to work out how to avoid the 'Constant
      > subroutine redefined' warnings in the error log, followed by the
      > 'Prototype missmatch:' error upon subsequent hits to the apache child
      > process - but, I have not been able to find an easy solution. The
      > warnings are caused by the 'flush_namespace' routine of Apache::PerlRun
      > which attempts to reset/nullify everything - including constants. When a
      > constant is redefined it causes a warning in the error_log, and when the
      > constant gets reset upon the next run of the script the prototype doesnt
      > match as its reset incorrectly.
      >
      > I found a message from Stass Beckman saying that you could use a
      > $SIG{__WARN__} handler to filter the warnings. This works for the
      > 'Constant subroutine redefined' warnings, but not the 'Prototype
      > missmatch:' warnings (even thou I modified it to take both into
      > account), no matter where i add the $SIG{__WARN__} handler it never gets
      > called in the case of 'Prototype missmatch:' - not even when its defined
      > in the startup.pl
      >
      > So I decided to work out a way to modify Apache::PerlRun so that it
      > did not redefine constants. There is no need to nullify constants as
      > they will not and CAN NOT change between child instances, and
      > documentation indicates that the 'Constant subroutine redefined' warning
      > means that the original value will be retained anyway (i.e. you cant
      > change a constants value).
      >
      > Constants in perl are anonymous code references with a blank
      > prototype, that is how they are created within constant.pm here is a
      > snippet:
      >
      > *{$fullname} = sub () { };
      >
      > So if you had:
      >
      > use constant TRUE => 1;
      >
      > it would become:
      >
      > *{$fullname} = sub () { 1 };
      >
      > where $fullname was main::TRUE
      >
      > When a subroutine is defined with a prototype of '()' and it returns a
      > constant result when compiled, it becomes a 'constant subroutine'.
      > Hence, constants are meerly constant subroutines.
      >
      > So now for the changes I made to PerlRun.pm, below is the original
      > code:
      >
      >
      > if (defined &$fullname) {
      > no warnings;
      > local $^W = 0;
      > if (defined(my $p = prototype $fullname)) {
      > *{$fullname} = eval "sub ($p) {}";
      > }
      > else {
      > *{$fullname} = sub {};
      > }
      > undef &$fullname;
      > }
      >
      > So, this code would reset every subroutine to a blank anonymous
      > subroutine, using the correct (current) prototype. And then undefine it.
      >
      > My patch:
      >
      > if (defined &$fullname) {
      > no warnings;
      > local $^W = 0;
      > if (defined(my $p = prototype $fullname)) {
      > # We DONT want to redefine constant subroutines (sub ())
      > if ($p) {
      > *{$fullname} = eval "sub ($p) {}";
      > undef &$fullname;
      > }
      > }
      > else {
      > *{$fullname} = sub {};
      > undef &$fullname;
      > }
      > }
      >
      > This code will reset every subroutine that does not have an empty
      > prototype and then undef it. So basically the 'sub () {}' defined
      > subroutines are not reset (but sub {} and sub ($) {} are reset).
      >
      > Now, im aware this is not an ideal solution due to the fact that any
      > subroutines declared in a script with a () prototype will not be reset.
      > But on the flip side of the coin all constants will be left intact and
      > any warnings in the error log avoided. My question is, what caveats
      > would there be in not resetting a subroutine? I have ran some tests to
      > see how subroutines setup in this way would work and the tests appear to
      > be good.
      >
      > For example:
      >
      > print STDERR 'time_constant = '. &time_constant(). "\n";
      > sub time_constant () {
      > time. ' '. $$;
      > }
      >
      > running under 'httpd -X'
      >
      > would produce a different time each request, and the same process id.
      >
      > as did..
      >
      > my $time_constant = sub () { time. ' '. $$ };
      > print STDERR 'var time_constant = '. &{$time_constant}. "\n";
      >
      >
      > Sorry this email is a tad long, but its quite complicated to explain.
      >
      > Cheers,
      >
      >
      > --
      > David Radunz,
      > Developer / Programmer
      >
      > Netspace Online Systems Pty Ltd
      > Ground Floor, 293 Camberwell Road
      > Camberwell, Victoria 3124
      > Ph: +613 9811 0087
      > Fx: +613 9811 0044
      > Mo: +614 0549 9719
      > Em: david.radunz@...
      >
      > This email and any files transmitted with it are confidential and intended solely for the
      > use of the individual or entity to whom they are addressed. Please notify the sender
      > immediately by email if you have received this email by mistake and delete this email
      > from your system. Please note that any views or opinions presented in this email are solely
      > those of the author and do not necessarily represent those of the organisation.
      > Finally, the recipient should check this email and any attachments for the presence of
      > viruses. The organisation accepts no liability for any damage caused by any virus
      > transmitted by this email.
      --
      David Radunz,
      Developer / Programmer

      Netspace Online Systems Pty Ltd
      Ground Floor, 293 Camberwell Road
      Camberwell, Victoria 3124
      Ph: +613 9811 0087
      Fx: +613 9811 0044
      Mo: +614 0549 9719
      Em: david.radunz@...

      --
      Report problems: http://perl.apache.org/bugs/
      Mail list info: http://perl.apache.org/maillist/modperl.html
      List etiquette: http://perl.apache.org/maillist/email-etiquette.html
    • Show all 16 messages in this topic