mirror of
https://github.com/znc/znc.git
synced 2026-08-06 08:52:57 +02:00
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
This commit is contained in:
@@ -189,6 +189,12 @@ typedef vector<pair<CString, CString> > VPair;
|
|||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
void _CleanupStash(const CString& sModname) {
|
||||||
|
hv_clear(gv_stashpv(sModname.c_str(), 0));
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
%perlcode %{
|
%perlcode %{
|
||||||
package ZNC;
|
package ZNC;
|
||||||
*CONTINUE = *ZNC::CModule::CONTINUE;
|
*CONTINUE = *ZNC::CModule::CONTINUE;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package ZNC::Core;
|
|||||||
my $uuidtype;
|
my $uuidtype;
|
||||||
my $uuidgen;
|
my $uuidgen;
|
||||||
our %pmods;
|
our %pmods;
|
||||||
|
my %modrefcount;
|
||||||
|
|
||||||
sub Init {
|
sub Init {
|
||||||
if (eval { require Data::UUID }) {
|
if (eval { require Data::UUID }) {
|
||||||
@@ -53,6 +54,8 @@ sub CreateUUID {
|
|||||||
|
|
||||||
sub unloadByIDUser {
|
sub unloadByIDUser {
|
||||||
my ($id, $user) = @_;
|
my ($id, $user) = @_;
|
||||||
|
my $modpath = $pmods{$id}{_cmod}->GetModPath;
|
||||||
|
my $modname = $pmods{$id}{_cmod}->GetModName;
|
||||||
$pmods{$id}->OnShutdown;
|
$pmods{$id}->OnShutdown;
|
||||||
$user->GetModules->removeModule($pmods{$id}{_cmod});
|
$user->GetModules->removeModule($pmods{$id}{_cmod});
|
||||||
delete $pmods{$id}{_cmod};# Just for the case
|
delete $pmods{$id}{_cmod};# Just for the case
|
||||||
@@ -60,6 +63,11 @@ sub unloadByIDUser {
|
|||||||
delete $pmods{$id}{_ptimers};
|
delete $pmods{$id}{_ptimers};
|
||||||
delete $pmods{$id}{_sockets};
|
delete $pmods{$id}{_sockets};
|
||||||
delete $pmods{$id};
|
delete $pmods{$id};
|
||||||
|
unless (--$modrefcount{$modname}) {
|
||||||
|
say "Unloading $modpath from perl";
|
||||||
|
ZNC::_CleanupStash($modname);
|
||||||
|
delete $INC{$modpath};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub UnloadModule {
|
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]");
|
ZNC::CModules::FindModPath("$modname.pm", $modpath, $datapath) or return ($ZNC::Perl_NotFound, "Unable to find module [$modname]");
|
||||||
$modpath = $modpath->GetPerlStr;
|
$modpath = $modpath->GetPerlStr;
|
||||||
return ($ZNC::Perl_LoadError, "Incorrect perl module.") unless IsModule $modpath, $modname;
|
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;
|
my $id = CreateUUID;
|
||||||
$datapath = $datapath->GetPerlStr;
|
$datapath = $datapath->GetPerlStr;
|
||||||
$datapath =~ s/\.pm$//;
|
$datapath =~ s/\.pm$//;
|
||||||
|
|||||||
Reference in New Issue
Block a user