perl-modperl mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mark <m...@immermail.com>
Subject Re: Apache2::Reload problem (ModPerl::Util bug)
Date Sun, 29 May 2005 17:52:36 GMT
Mark wrote:
> In 2.0.0, if there are heirarchical packages, and Apache2::Reload is
> configured to reload the 'parent', it blows away the 'children' package
> namespaces (and doesn't reload the children.)  For example, if @INC has:
> 
> Fubar.pm
> Fubar/Child.pm
> 
> And Apache2::Reload reloads package Fubar, it blows away
> Fubar::Child::* and only reloads file Fubar.pm.   Only a server
> restart can recover from this point.
> 
> The actual unloading work is done by ModPerl::Util::unload_package(),
> whose behavior is contrary to the docs, which say:
> 
>   "unload_package()" takes care to leave sub-stashes intact while
>   deleting the requested stash. So for example if "CGI" and "CGI::Carp"
>   are loaded, calling "unload_package('CGI')" won't affect "CGI::Carp".
> 
> 
> I only partly understand how unload_package() works, but it seems to
> just iterate over symbols in the package and blow them away, without
> regard for the actual file from which the symbol was instantiated.
> 
> I tried modifying the code to skip over symbols that correspond
> to a key in %INC, which seems logical and works correctly in my tests,
> but may not be a complete or perfect solution for reasons beyond
> my current testing/thinking.  However, in my tests, it works correctly
> if either the parent package, child package, or both are modified.
> 
> Comments/suggestions about the correctness of this patch requested.

Correction. Ignore previous patch.  It only worked one level of
heirarchy.  Correct patch is:

*** ./blib/lib/ModPerl/Util.pm  2005-05-22 10:14:19.000000000 -0700
--- /usr/lib/perl5/site_perl/5.8.5/i686-linux/ModPerl/Util.pm   2005-05-29 10:47:37.000000000
-0700
***************
*** 37,56 ****
--- 37,61 ----
       my $package = shift;
       no strict 'refs';
       my $tab = \%{ $package . '::' };

       # below we assign to a symbol first before undef'ing it, to avoid
       # nuking aliases. If we undef directly we may undef not only the
       # alias but the original function as well

       for (keys %$tab) {
           my $fullname = join '::', $package, $_;
+         if (my ($subpackage) = $fullname =~ /(.*)::/) {
+                 $subpackage =~ s[::][/]g;
+                 $subpackage .= ".pm";
+                 next if exists $INC{$subpackage};
+         }
           # code/hash/array/scalar might be imported make sure the gv
           # does not point elsewhere before undefing each
           if (%$fullname) {
               *{$fullname} = {};
               undef %$fullname;
           }
           if (@$fullname) {
               *{$fullname} = [];
               undef @$fullname;
           }


Mime
View raw message