Apache2::Reload problem (ModPerl::Util bug)
[prev]
[thread]
[next]
[Date index for 2005/05/29]
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.
Thanks.
*** ./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:09:02.000000000 -0700
***************
*** 36,55 ****
--- 36,58 ----
sub unload_package_pp {
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) {
+ if (my ($subpackage) = /(.*)::/) {
+ next if exists $INC{"$package/$subpackage.pm"};
+ }
my $fullname = join '::', $package, $_;
# 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;
 |
Apache2::Reload problem (ModPerl::Util bug)
Mark 17:32 on 29 May 2005
|