From ce45917cc034abe9e2ea85dcff8d44e493597ebe Mon Sep 17 00:00:00 2001 From: darthgandalf Date: Sun, 5 Dec 2010 09:38:25 +0000 Subject: [PATCH] Unload perl modules when they are unloaded. This should make /znc reloadmod and /znc updatemod to work as expected. So developers don't need to restart znc each time when debugging perl modules anymore. git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@2184 726aef4b-f618-498e-8847-2d620e286838 --- modules/modperl/modperl.i | 6 ++++++ modules/modperl/startup.pl | 19 ++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/modules/modperl/modperl.i b/modules/modperl/modperl.i index 051964d3..424c895b 100644 --- a/modules/modperl/modperl.i +++ b/modules/modperl/modperl.i @@ -189,6 +189,12 @@ typedef vector > VPair; } %} +%inline %{ + void _CleanupStash(const CString& sModname) { + hv_clear(gv_stashpv(sModname.c_str(), 0)); + } +%} + %perlcode %{ package ZNC; *CONTINUE = *ZNC::CModule::CONTINUE; diff --git a/modules/modperl/startup.pl b/modules/modperl/startup.pl index adc912b7..ef818157 100644 --- a/modules/modperl/startup.pl +++ b/modules/modperl/startup.pl @@ -18,6 +18,7 @@ package ZNC::Core; my $uuidtype; my $uuidgen; our %pmods; +my %modrefcount; sub Init { if (eval { require Data::UUID }) { @@ -53,6 +54,8 @@ sub CreateUUID { sub unloadByIDUser { my ($id, $user) = @_; + my $modpath = $pmods{$id}{_cmod}->GetModPath; + my $modname = $pmods{$id}{_cmod}->GetModName; $pmods{$id}->OnShutdown; $user->GetModules->removeModule($pmods{$id}{_cmod}); delete $pmods{$id}{_cmod};# Just for the case @@ -60,6 +63,11 @@ sub unloadByIDUser { delete $pmods{$id}{_ptimers}; delete $pmods{$id}{_sockets}; delete $pmods{$id}; + unless (--$modrefcount{$modname}) { + say "Unloading $modpath from perl"; + ZNC::_CleanupStash($modname); + delete $INC{$modpath}; + } } sub UnloadModule { @@ -89,7 +97,16 @@ sub LoadModule { ZNC::CModules::FindModPath("$modname.pm", $modpath, $datapath) or return ($ZNC::Perl_NotFound, "Unable to find module [$modname]"); $modpath = $modpath->GetPerlStr; return ($ZNC::Perl_LoadError, "Incorrect perl module.") unless IsModule $modpath, $modname; - require $modpath; + eval { + require $modpath; + }; + if ($@) { + # modrefcount was 0 before this, otherwise it couldn't die. + # so can safely remove module from %INC + delete $INC{$modpath}; + die $@; + } + $modrefcount{$modname}++; my $id = CreateUUID; $datapath = $datapath->GetPerlStr; $datapath =~ s/\.pm$//;