mirror of
https://github.com/znc/znc.git
synced 2026-03-28 17:42:41 +01:00
Unload all python modules when modpython is unloaded.
Only user modules were unloaded before.
This commit is contained in:
@@ -320,28 +320,15 @@ public:
|
||||
}
|
||||
|
||||
virtual ~CModPython() {
|
||||
const map<CString, CUser*>& users = CZNC::Get().GetUserMap();
|
||||
for (map<CString, CUser*>::const_iterator i = users.begin(); i != users.end(); ++i) {
|
||||
CModules& M = i->second->GetModules();
|
||||
bool cont;
|
||||
do {
|
||||
cont = false;
|
||||
for (CModules::iterator it = M.begin(); it != M.end(); ++it) {
|
||||
CModule* m = *it;
|
||||
CPyModule* mod = AsPyModule(m);
|
||||
if (mod) {
|
||||
cont = true;
|
||||
bool bSuccess = false;
|
||||
CString sRetMsg;
|
||||
OnModuleUnloading(mod, bSuccess, sRetMsg);
|
||||
if (!bSuccess) {
|
||||
DEBUG("Error unloading python module in ~CModPython: " << sRetMsg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (cont);
|
||||
}
|
||||
PyObject* pyFunc = PyObject_GetAttrString(m_PyZNCModule, "unload_all");
|
||||
PyObject* pyRes = PyObject_CallFunctionObjArgs(pyFunc, NULL);
|
||||
if (!pyRes) {
|
||||
CString sRetMsg = GetPyExceptionStr();
|
||||
DEBUG("modpython tried to unload all modules in its destructor, but: " << sRetMsg);
|
||||
}
|
||||
Py_CLEAR(pyRes);
|
||||
Py_CLEAR(pyFunc);
|
||||
|
||||
Py_CLEAR(m_PyFormatException);
|
||||
Py_CLEAR(m_PyZNCModule);
|
||||
Py_Finalize();
|
||||
|
||||
@@ -423,6 +423,7 @@ def find_open(modname):
|
||||
# nothing found
|
||||
return (None, None)
|
||||
|
||||
_py_modules = set()
|
||||
|
||||
def load_module(modname, args, module_type, user, network, retmsg, modpython):
|
||||
'''Returns 0 if not found, 1 on loading error, 2 on success'''
|
||||
@@ -450,23 +451,24 @@ def load_module(modname, args, module_type, user, network, retmsg, modpython):
|
||||
module.SetArgs(args)
|
||||
module.SetModPath(pymodule.__file__)
|
||||
module.SetType(module_type)
|
||||
_py_modules.add(module)
|
||||
|
||||
if module_type == CModInfo.UserModule:
|
||||
if not user:
|
||||
retmsg.s = "Module [modpython] needs user for for UserModule."
|
||||
retmsg.s = "Module [{}] is UserModule and needs user.".format(modname)
|
||||
unload_module(module)
|
||||
return 1
|
||||
user.GetModules().push_back(module._cmod)
|
||||
elif module_type == CModInfo.NetworkModule:
|
||||
if not network:
|
||||
retmsg.s = "Module [modpython] needs a network for for NetworkModule."
|
||||
retmsg.s = "Module [{}] is Network module and needs a network.".format(modname)
|
||||
unload_module(module)
|
||||
return 1
|
||||
network.GetModules().push_back(module._cmod)
|
||||
elif module_type == CModInfo.GlobalModule:
|
||||
CZNC.Get().GetModules().push_back(module._cmod)
|
||||
else:
|
||||
retmsg.s = "Module [modpython] doesn't support module type."
|
||||
retmsg.s = "Module [{}] doesn't support that module type.".format(modname)
|
||||
unload_module(module)
|
||||
return 1
|
||||
|
||||
@@ -508,6 +510,7 @@ def load_module(modname, args, module_type, user, network, retmsg, modpython):
|
||||
|
||||
def unload_module(module):
|
||||
module.OnShutdown()
|
||||
_py_modules.discard(module)
|
||||
cmod = module._cmod
|
||||
if module.GetType() == CModInfo.UserModule:
|
||||
cmod.GetUser().GetModules().removeModule(cmod)
|
||||
@@ -520,6 +523,12 @@ def unload_module(module):
|
||||
del cmod
|
||||
|
||||
|
||||
def unload_all():
|
||||
while len(_py_modules) > 0:
|
||||
mod = _py_modules.pop()
|
||||
unload_module(mod)
|
||||
|
||||
|
||||
def get_mod_info(modname, retmsg, modinfo):
|
||||
'''0-not found, 1-error, 2-success'''
|
||||
pymodule, datadir = find_open(modname)
|
||||
|
||||
Reference in New Issue
Block a user