components/apache2-modules/mod_perl/patches/Reload.patch
changeset 4788 159f02dfcdd3
parent 4787 9df2862df01c
child 4789 4f6fec688e48
equal deleted inserted replaced
4787:9df2862df01c 4788:159f02dfcdd3
     1 --- /dev/null	Fri Oct 16 06:02:02 2009
       
     2 +++ mod_perl-2.0.4/lib/Apache2/Reload.pm	Sun Nov 19 15:31:40 2006
       
     3 @@ -0,0 +1,185 @@
       
     4 +# Licensed to the Apache Software Foundation (ASF) under one or more
       
     5 +# contributor license agreements.  See the NOTICE file distributed with
       
     6 +# this work for additional information regarding copyright ownership.
       
     7 +# The ASF licenses this file to You under the Apache License, Version 2.0
       
     8 +# (the "License"); you may not use this file except in compliance with
       
     9 +# the License.  You may obtain a copy of the License at
       
    10 +#
       
    11 +#     http://www.apache.org/licenses/LICENSE-2.0
       
    12 +#
       
    13 +# Unless required by applicable law or agreed to in writing, software
       
    14 +# distributed under the License is distributed on an "AS IS" BASIS,
       
    15 +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    16 +# See the License for the specific language governing permissions and
       
    17 +# limitations under the License.
       
    18 +#
       
    19 +package Apache2::Reload;
       
    20 +
       
    21 +use strict;
       
    22 +use warnings FATAL => 'all';
       
    23 +
       
    24 +use mod_perl2;
       
    25 +
       
    26 +our $VERSION = '0.09';
       
    27 +
       
    28 +use Apache2::Const -compile => qw(OK);
       
    29 +
       
    30 +use Apache2::Connection;
       
    31 +use Apache2::ServerUtil;
       
    32 +use Apache2::RequestUtil;
       
    33 +
       
    34 +use ModPerl::Util ();
       
    35 +
       
    36 +use vars qw(%INCS %Stat $TouchTime);
       
    37 +
       
    38 +%Stat = ($INC{"Apache2/Reload.pm"} => time);
       
    39 +
       
    40 +$TouchTime = time;
       
    41 +
       
    42 +sub import {
       
    43 +    my $class = shift;
       
    44 +    my ($package, $file) = (caller)[0,1];
       
    45 +
       
    46 +    $class->register_module($package, $file);
       
    47 +}
       
    48 +
       
    49 +sub package_to_module {
       
    50 +    my $package = shift;
       
    51 +    $package =~ s/::/\//g;
       
    52 +    $package .= ".pm";
       
    53 +    return $package;
       
    54 +}
       
    55 +
       
    56 +sub module_to_package {
       
    57 +    my $module = shift;
       
    58 +    $module =~ s/\//::/g;
       
    59 +    $module =~ s/\.pm$//g;
       
    60 +    return $module;
       
    61 +}
       
    62 +
       
    63 +sub register_module {
       
    64 +    my ($class, $package, $file) = @_;
       
    65 +    my $module = package_to_module($package);
       
    66 +
       
    67 +    if ($file) {
       
    68 +        $INCS{$module} = $file;
       
    69 +    }
       
    70 +    else {
       
    71 +        $file = $INC{$module};
       
    72 +        return unless $file;
       
    73 +        $INCS{$module} = $file;
       
    74 +    }
       
    75 +}
       
    76 +
       
    77 +sub unregister_module {
       
    78 +    my ($class, $package) = @_;
       
    79 +    my $module = package_to_module($package);
       
    80 +    delete $INCS{$module};
       
    81 +}
       
    82 +
       
    83 +# the first argument is:
       
    84 +# $c if invoked as 'PerlPreConnectionHandler'
       
    85 +# $r if invoked as 'PerlInitHandler'
       
    86 +sub handler {
       
    87 +    my $o = shift;
       
    88 +    $o = $o->base_server if ref($o) eq 'Apache2::Connection';
       
    89 +
       
    90 +    my $DEBUG = ref($o) && (lc($o->dir_config("ReloadDebug") || '') eq 'on');
       
    91 +
       
    92 +    my $TouchFile = ref($o) && $o->dir_config("ReloadTouchFile");
       
    93 +
       
    94 +    my $ConstantRedefineWarnings = ref($o) && 
       
    95 +        (lc($o->dir_config("ReloadConstantRedefineWarnings") || '') eq 'off') 
       
    96 +            ? 0 : 1;
       
    97 +
       
    98 +    my $TouchModules;
       
    99 +
       
   100 +    if ($TouchFile) {
       
   101 +        warn "Checking mtime of $TouchFile\n" if $DEBUG;
       
   102 +        my $touch_mtime = (stat $TouchFile)[9] || return Apache2::Const::OK;
       
   103 +        return Apache2::Const::OK unless $touch_mtime > $TouchTime;
       
   104 +        $TouchTime = $touch_mtime;
       
   105 +        open my $fh, $TouchFile or die "Can't open '$TouchFile': $!";
       
   106 +        $TouchModules = <$fh>;
       
   107 +        chomp $TouchModules if $TouchModules;
       
   108 +    }
       
   109 +
       
   110 +    if (ref($o) && (lc($o->dir_config("ReloadAll") || 'on') eq 'on')) {
       
   111 +        *Apache2::Reload::INCS = \%INC;
       
   112 +    }
       
   113 +    else {
       
   114 +        *Apache2::Reload::INCS = \%INCS;
       
   115 +        my $ExtraList = 
       
   116 +                $TouchModules || 
       
   117 +                (ref($o) && $o->dir_config("ReloadModules")) || 
       
   118 +                '';
       
   119 +        my @extra = split /\s+/, $ExtraList;
       
   120 +        foreach (@extra) {
       
   121 +            if (/(.*)::\*$/) {
       
   122 +                my $prefix = $1;
       
   123 +                $prefix =~ s/::/\//g;
       
   124 +                foreach my $match (keys %INC) {
       
   125 +                    if ($match =~ /^\Q$prefix\E/) {
       
   126 +                        $Apache2::Reload::INCS{$match} = $INC{$match};
       
   127 +                    }
       
   128 +                }
       
   129 +            }
       
   130 +            else {
       
   131 +                Apache2::Reload->register_module($_);
       
   132 +            }
       
   133 +        }
       
   134 +    }
       
   135 +
       
   136 +    my $ReloadDirs = ref($o) && $o->dir_config("ReloadDirectories");
       
   137 +    my @watch_dirs = split(/\s+/, $ReloadDirs||'');
       
   138 +    
       
   139 +    my @changed;
       
   140 +    foreach my $key (sort { $a cmp $b } keys %Apache2::Reload::INCS) {
       
   141 +        my $file = $Apache2::Reload::INCS{$key};
       
   142 +
       
   143 +        next unless defined $file;
       
   144 +        next if @watch_dirs && !grep { $file =~ /^$_/ } @watch_dirs;
       
   145 +        warn "Apache2::Reload: Checking mtime of $key\n" if $DEBUG;
       
   146 +
       
   147 +        my $mtime = (stat $file)[9];
       
   148 +
       
   149 +        unless (defined($mtime) && $mtime) {
       
   150 +            for (@INC) {
       
   151 +                $mtime = (stat "$_/$file")[9];
       
   152 +                last if defined($mtime) && $mtime;
       
   153 +            }
       
   154 +        }
       
   155 +
       
   156 +        warn("Apache2::Reload: Can't locate $file\n"), next
       
   157 +            unless defined $mtime and $mtime;
       
   158 +
       
   159 +        unless (defined $Stat{$file}) {
       
   160 +            $Stat{$file} = $^T;
       
   161 +        }
       
   162 +
       
   163 +        if ($mtime > $Stat{$file}) {
       
   164 +            push @changed, $key;
       
   165 +        }
       
   166 +        $Stat{$file} = $mtime;
       
   167 +    }
       
   168 +    
       
   169 +    #First, let's unload all changed modules
       
   170 +    foreach my $module (@changed) {
       
   171 +        my $package = module_to_package($module);
       
   172 +        ModPerl::Util::unload_package($package);
       
   173 +    }
       
   174 +    
       
   175 +    #Then, let's reload them all, so that module dependencies can satisfy
       
   176 +    #themselves in the correct order.
       
   177 +    foreach my $module (@changed) {
       
   178 +        my $package = module_to_package($module);
       
   179 +        require $module;
       
   180 +        warn("Apache2::Reload: process $$ reloading $package from $module\n")
       
   181 +            if $DEBUG;
       
   182 +    }
       
   183 +
       
   184 +    return Apache2::Const::OK;
       
   185 +}
       
   186 +
       
   187 +1;
       
   188 +__END__
       
   189 --- /dev/null	Fri Oct 16 06:02:02 2009
       
   190 +++ mod_perl-2.0.4/docs/api/Apache2/Reload.pod	Sun Nov 19 15:32:13 2006
       
   191 @@ -1,0 +1,380 @@
       
   192 +=head1 NAME
       
   193 +
       
   194 +Apache2::Reload - Reload Perl Modules when Changed on Disk
       
   195 +
       
   196 +=head1 Synopsis
       
   197 +
       
   198 +  # Monitor and reload all modules in %INC:
       
   199 +  # httpd.conf:
       
   200 +  PerlModule Apache2::Reload
       
   201 +  PerlInitHandler Apache2::Reload
       
   202 +
       
   203 +  # when working with protocols and connection filters
       
   204 +  # PerlPreConnectionHandler Apache2::Reload
       
   205 +
       
   206 +  # Reload groups of modules:
       
   207 +  # httpd.conf:
       
   208 +  PerlModule Apache2::Reload
       
   209 +  PerlInitHandler Apache2::Reload
       
   210 +  PerlSetVar ReloadAll Off
       
   211 +  PerlSetVar ReloadModules "ModPerl::* Apache2::*"
       
   212 +  #PerlSetVar ReloadDebug On
       
   213 +  
       
   214 +  # Reload a single module from within itself:
       
   215 +  package My::Apache2::Module;
       
   216 +  use Apache2::Reload;
       
   217 +  sub handler { ... }
       
   218 +  1;
       
   219 +
       
   220 +=head1 Description
       
   221 +
       
   222 +C<Apache2::Reload> reloads modules that change on the disk.
       
   223 +
       
   224 +When Perl pulls a file via C<require>, it stores the filename in the
       
   225 +global hash C<%INC>.  The next time Perl tries to C<require> the same
       
   226 +file, it sees the file in C<%INC> and does not reload from disk.  This
       
   227 +module's handler can be configured to iterate over the modules in
       
   228 +C<%INC> and reload those that have changed on disk or only specific
       
   229 +modules that have registered themselves with C<Apache2::Reload>. It can
       
   230 +also do the check for modified modules, when a special touch-file has
       
   231 +been modified.
       
   232 +
       
   233 +Note that C<Apache2::Reload> operates on the current context of
       
   234 +C<@INC>.  Which means, when called as a C<Perl*Handler> it will not
       
   235 +see C<@INC> paths added or removed by C<ModPerl::Registry> scripts, as
       
   236 +the value of C<@INC> is saved on server startup and restored to that
       
   237 +value after each request.  In other words, if you want
       
   238 +C<Apache2::Reload> to work with modules that live in custom C<@INC>
       
   239 +paths, you should modify C<@INC> when the server is started.  Besides,
       
   240 +C<'use lib'> in the startup script, you can also set the C<PERL5LIB>
       
   241 +variable in the httpd's environment to include any non-standard 'lib'
       
   242 +directories that you choose.  For example, to accomplish that you can
       
   243 +include a line:
       
   244 +
       
   245 +  PERL5LIB=/home/httpd/perl/extra; export PERL5LIB
       
   246 +
       
   247 +in the script that starts Apache. Alternatively, you can set this
       
   248 +environment variable in I<httpd.conf>:
       
   249 +
       
   250 +  PerlSetEnv PERL5LIB /home/httpd/perl/extra
       
   251 +
       
   252 +=head2 Monitor All Modules in C<%INC>
       
   253 +
       
   254 +To monitor and reload all modules in C<%INC> at the beginning of
       
   255 +request's processing, simply add the following configuration to your
       
   256 +I<httpd.conf>:
       
   257 +
       
   258 +  PerlModule Apache2::Reload
       
   259 +  PerlInitHandler Apache2::Reload
       
   260 +
       
   261 +When working with connection filters and protocol modules
       
   262 +C<Apache2::Reload> should be invoked in the pre_connection stage:
       
   263 +
       
   264 +  PerlPreConnectionHandler Apache2::Reload
       
   265 +
       
   266 +See also the discussion on
       
   267 +C<L<PerlPreConnectionHandler|docs::2.0::user::handlers::protocols/PerlPreConnectionHandler>>.
       
   268 +
       
   269 +=head2 Register Modules Implicitly
       
   270 +
       
   271 +To only reload modules that have registered with C<Apache2::Reload>,
       
   272 +add the following to the I<httpd.conf>:
       
   273 +
       
   274 +  PerlModule Apache2::Reload
       
   275 +  PerlInitHandler Apache2::Reload
       
   276 +  PerlSetVar ReloadAll Off
       
   277 +  # ReloadAll defaults to On
       
   278 +
       
   279 +Then any modules with the line:
       
   280 +
       
   281 +  use Apache2::Reload;
       
   282 +
       
   283 +Will be reloaded when they change.
       
   284 +
       
   285 +=head2 Register Modules Explicitly
       
   286 +
       
   287 +You can also register modules explicitly in your I<httpd.conf> file
       
   288 +that you want to be reloaded on change:
       
   289 +
       
   290 +  PerlModule Apache2::Reload
       
   291 +  PerlInitHandler Apache2::Reload
       
   292 +  PerlSetVar ReloadAll Off
       
   293 +  PerlSetVar ReloadModules "My::Foo My::Bar Foo::Bar::Test"
       
   294 +
       
   295 +Note that these are split on whitespace, but the module list B<must>
       
   296 +be in quotes, otherwise Apache tries to parse the parameter list.
       
   297 +
       
   298 +The C<*> wild character can be used to register groups of files under
       
   299 +the same namespace. For example the setting:
       
   300 +
       
   301 +  PerlSetVar ReloadModules "ModPerl::* Apache2::*"
       
   302 +
       
   303 +will monitor all modules under the namespaces C<ModPerl::> and
       
   304 +C<Apache2::>.
       
   305 +
       
   306 +=head2 Monitor Only Certain Sub Directories
       
   307 +
       
   308 +To reload modules only in certain directories (and their
       
   309 +subdirectories) add the following to the I<httpd.conf>:
       
   310 +
       
   311 +  PerlModule Apache2::Reload
       
   312 +  PerlInitHandler Apache2::Reload
       
   313 +  PerlSetVar ReloadDirectories "/tmp/project1 /tmp/project2"
       
   314 +
       
   315 +You can further narrow the list of modules to be reloaded from the
       
   316 +chosen directories with C<ReloadModules> as in:
       
   317 +
       
   318 +  PerlModule Apache2::Reload
       
   319 +  PerlInitHandler Apache2::Reload
       
   320 +  PerlSetVar ReloadDirectories "/tmp/project1 /tmp/project2"
       
   321 +  PerlSetVar ReloadAll Off
       
   322 +  PerlSetVar ReloadModules "MyApache2::*"
       
   323 +
       
   324 +In this configuration example only modules from the namespace
       
   325 +C<MyApache2::> found in the directories I</tmp/project1/> and
       
   326 +I</tmp/project2/> (and their subdirectories) will be reloaded.
       
   327 +
       
   328 +=head2 Special "Touch" File
       
   329 +
       
   330 +You can also declare a file, which when gets C<touch(1)>ed, causes the
       
   331 +reloads to be performed. For example if you set:
       
   332 +
       
   333 +  PerlSetVar ReloadTouchFile /tmp/reload_modules
       
   334 +
       
   335 +and don't C<touch(1)> the file I</tmp/reload_modules>, the reloads
       
   336 +won't happen until you go to the command line and type:
       
   337 +
       
   338 +  % touch /tmp/reload_modules
       
   339 +
       
   340 +When you do that, the modules that have been changed, will be
       
   341 +magically reloaded on the next request. This option works with any
       
   342 +mode described before.
       
   343 +
       
   344 +=head2 Unregistering a module
       
   345 +
       
   346 +In some cases, it might be necessary to explicitely stop reloading
       
   347 +a module.
       
   348 +
       
   349 +  Apache2::Reload->unregister_module('Some::Module');
       
   350 +
       
   351 +But be carefull, since unregistering a module in this way will only
       
   352 +do so for the current interpreter. This feature should be used with
       
   353 +care.
       
   354 +
       
   355 +=head1 Performance Issues
       
   356 +
       
   357 +This module is perfectly suited for a development environment. Though
       
   358 +it's possible that you would like to use it in a production
       
   359 +environment, since with C<Apache2::Reload> you don't have to restart
       
   360 +the server in order to reload changed modules during software
       
   361 +updates. Though this convenience comes at a price:
       
   362 +
       
   363 +=over
       
   364 +
       
   365 +=item *
       
   366 +
       
   367 +If the "touch" file feature is used, C<Apache2::Reload> has to stat(2)
       
   368 +the touch file on each request, which adds a slight but most likely
       
   369 +insignificant overhead to response times. Otherwise C<Apache2::Reload>
       
   370 +will stat(2) each registered module or even worse--all modules in
       
   371 +C<%INC>, which will significantly slow everything down.
       
   372 +
       
   373 +=item *
       
   374 +
       
   375 +Once the child process reloads the modules, the memory used by these
       
   376 +modules is not shared with the parent process anymore. Therefore the
       
   377 +memory consumption may grow significantly.
       
   378 +
       
   379 +=back
       
   380 +
       
   381 +Therefore doing a full server stop and restart is probably a better
       
   382 +solution.
       
   383 +
       
   384 +=head1 Debug
       
   385 +
       
   386 +If you aren't sure whether the modules that are supposed to be
       
   387 +reloaded, are actually getting reloaded, turn the debug mode on:
       
   388 +
       
   389 +  PerlSetVar ReloadDebug On
       
   390 +
       
   391 +=head1 Caveats
       
   392 +
       
   393 +=head2 Problems With Reloading Modules Which Do Not Declare Their Package Name
       
   394 +
       
   395 +If you modify modules, which don't declare their C<package>, and rely on
       
   396 +C<Apache2::Reload> to reload them, you may encounter problems: i.e.,
       
   397 +it'll appear as if the module wasn't reloaded when in fact it
       
   398 +was. This happens because when C<Apache2::Reload> C<require()>s such a
       
   399 +module all the global symbols end up in the C<Apache2::Reload>
       
   400 +namespace!  So the module does get reloaded and you see the compile
       
   401 +time errors if there are any, but the symbols don't get imported to
       
   402 +the right namespace. Therefore the old version of the code is running.
       
   403 +
       
   404 +
       
   405 +=head2 Failing to Find a File to Reload
       
   406 +
       
   407 +C<Apache2::Reload> uses C<%INC> to find the files on the filesystem. If
       
   408 +an entry for a certain filepath in C<%INC> is relative,
       
   409 +C<Apache2::Reload> will use C<@INC> to try to resolve that relative
       
   410 +path. Now remember that mod_perl freezes the value of C<@INC> at the
       
   411 +server startup, and you can modify it only for the duration of one
       
   412 +request when you need to load some module which is not in on of the
       
   413 +C<@INC> directories. So a module gets loaded, and registered in
       
   414 +C<%INC> with a relative path. Now when C<Apache2::Reload> tries to find
       
   415 +that module to check whether it has been modified, it can't find since
       
   416 +its directory is not in C<@INC>. So C<Apache2::Reload> will silently
       
   417 +skip that module.
       
   418 +
       
   419 +You can enable the C<Debug|/Debug> mode to see what C<Apache2::Reload>
       
   420 +does behind the scenes.
       
   421 +
       
   422 +
       
   423 +
       
   424 +=head2 Problems with Scripts Running with Registry Handlers that Cache the Code
       
   425 +
       
   426 +The following problem is relevant only to registry handlers that cache
       
   427 +the compiled script. For example it concerns
       
   428 +C<L<ModPerl::Registry|docs::2.0::api::ModPerl::Registry>> but not
       
   429 +C<L<ModPerl::PerlRun|docs::2.0::api::ModPerl::PerlRun>>.
       
   430 +
       
   431 +=head3 The Problem
       
   432 +
       
   433 +Let's say that there is a module C<My::Utils>:
       
   434 +
       
   435 +  #file:My/Utils.pm
       
   436 +  #----------------
       
   437 +  package My::Utils;
       
   438 +  BEGIN { warn __PACKAGE__ , " was reloaded\n" }
       
   439 +  use base qw(Exporter);
       
   440 +  @EXPORT = qw(colour);
       
   441 +  sub colour { "white" }
       
   442 +  1;
       
   443 +
       
   444 +And a registry script F<test.pl>:
       
   445 +
       
   446 +  #file:test.pl
       
   447 +  #------------
       
   448 +  use My::Utils;
       
   449 +  print "Content-type: text/plain\n\n";
       
   450 +  print "the color is " . colour();
       
   451 +
       
   452 +Assuming that the server is running in a single mode, we request the
       
   453 +script for the first time and we get the response:
       
   454 +
       
   455 +  the color is white
       
   456 +
       
   457 +Now we change F<My/Utils.pm>:
       
   458 +
       
   459 +  -  sub colour { "white" }
       
   460 +  +  sub colour { "red" }
       
   461 +
       
   462 +And issue the request again. C<Apache2::Reload> does its job and we can
       
   463 +see that C<My::Utils> was reloaded (look in the I<error_log>
       
   464 +file). However the script still returns:
       
   465 +
       
   466 +  the color is white
       
   467 +
       
   468 +=head3 The Explanation
       
   469 +
       
   470 +Even though F<My/Utils.pm> was reloaded, C<ModPerl::Registry>'s cached
       
   471 +code won't run 'C<use My::Utils;>' again (since it happens only once,
       
   472 +i.e. during the compile time). Therefore the script doesn't know that
       
   473 +the subroutine reference has been changed.
       
   474 +
       
   475 +This is easy to verify. Let's change the script to be:
       
   476 +
       
   477 +  #file:test.pl
       
   478 +  #------------
       
   479 +  use My::Utils;
       
   480 +  print "Content-type: text/plain\n\n";
       
   481 +  my $sub_int = \&colour;
       
   482 +  my $sub_ext = \&My::Utils::colour;
       
   483 +  print "int $sub_int\n";
       
   484 +  print "ext $sub_ext\n";
       
   485 +
       
   486 +Issue a request, you will see something similar to:
       
   487 +
       
   488 +  int CODE(0x8510af8)
       
   489 +  ext CODE(0x8510af8)
       
   490 +
       
   491 +As you can see both point to the same CODE reference (meaning that
       
   492 +it's the same symbol). After modifying F<My/Utils.pm> again:
       
   493 +
       
   494 +  -  sub colour { "red" }
       
   495 +  +  sub colour { "blue" }
       
   496 +
       
   497 +and calling the script on the secondnd time, we get:
       
   498 +
       
   499 +  int CODE(0x8510af8)
       
   500 +  ext CODE(0x851112c)
       
   501 +
       
   502 +You can see that the internal CODE reference is not the same as the
       
   503 +external one.
       
   504 +
       
   505 +=head3 The Solution
       
   506 +
       
   507 +There are two solutions to this problem:
       
   508 +
       
   509 +Solution 1: replace C<use()> with an explicit C<require()> +
       
   510 +C<import()>.
       
   511 +
       
   512 + - use My::Utils;
       
   513 + + require My::Utils; My::Utils->import();
       
   514 +
       
   515 +now the changed functions will be reimported on every request.
       
   516 +
       
   517 +Solution 2: remember to touch the script itself every time you change
       
   518 +the module that it requires.
       
   519 +
       
   520 +=head1 Threaded MPM and Multiple Perl Interpreters
       
   521 +
       
   522 +If you use C<Apache2::Reload> with a threaded MPM and multiple Perl
       
   523 +interpreters, the modules will be reloaded by each interpreter as they
       
   524 +are used, not every interpreters at once.  Similar to mod_perl 1.0
       
   525 +where each child has its own Perl interpreter, the modules are
       
   526 +reloaded as each child is hit with a request.
       
   527 +
       
   528 +If a module is loaded at startup, the syntax tree of each subroutine
       
   529 +is shared between interpreters (big win), but each subroutine has its
       
   530 +own padlist (where lexical my variables are stored).  Once
       
   531 +C<Apache2::Reload> reloads a module, this sharing goes away and each
       
   532 +Perl interpreter will have its own copy of the syntax tree for the
       
   533 +reloaded subroutines.
       
   534 +
       
   535 +
       
   536 +=head1 Pseudo-hashes
       
   537 +
       
   538 +The short summary of this is: Don't use pseudo-hashes. They are
       
   539 +deprecated since Perl 5.8 and are removed in 5.9.
       
   540 +
       
   541 +Use an array with constant indexes. Its faster in the general case,
       
   542 +its more guaranteed, and generally, it works.
       
   543 +
       
   544 +The long summary is that some work has been done to get this module
       
   545 +working with modules that use pseudo-hashes, but it's still broken in
       
   546 +the case of a single module that contains multiple packages that all
       
   547 +use pseudo-hashes.
       
   548 +
       
   549 +So don't do that.
       
   550 +
       
   551 +
       
   552 +
       
   553 +
       
   554 +=head1 Copyright
       
   555 +
       
   556 +mod_perl 2.0 and its core modules are copyrighted under
       
   557 +The Apache Software License, Version 2.0.
       
   558 +
       
   559 +
       
   560 +=head1 Authors
       
   561 +
       
   562 +Matt Sergeant, [email protected]
       
   563 +
       
   564 +Stas Bekman (porting to mod_perl 2.0)
       
   565 +
       
   566 +A few concepts borrowed from C<Stonehenge::Reload> by Randal Schwartz
       
   567 +and C<Apache::StatINC> (mod_perl 1.x) by Doug MacEachern and Ask
       
   568 +Bjoern Hansen.
       
   569 +
       
   570 +=cut
       
   571 +