mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-24 00:29:58 -05:00
- More fixes for reference counting for python module and clean up
failure code.
This commit is contained in:
parent
7696074fa9
commit
fc8bf269e9
2 changed files with 63 additions and 28 deletions
|
|
@ -1,3 +1,7 @@
|
||||||
|
29 June 2023: George
|
||||||
|
- More fixes for reference counting for python module and clean up
|
||||||
|
failure code.
|
||||||
|
|
||||||
29 June 2023: Wouter
|
29 June 2023: Wouter
|
||||||
- Fix python modules with multiple scripts, by incrementing reference
|
- Fix python modules with multiple scripts, by incrementing reference
|
||||||
counts.
|
counts.
|
||||||
|
|
|
||||||
|
|
@ -258,7 +258,7 @@ int pythonmod_init(struct module_env* env, int id)
|
||||||
|
|
||||||
/* Initialize module */
|
/* Initialize module */
|
||||||
FILE* script_py = NULL;
|
FILE* script_py = NULL;
|
||||||
PyObject* py_init_arg, *res;
|
PyObject* py_init_arg = NULL, *res = NULL;
|
||||||
PyGILState_STATE gil;
|
PyGILState_STATE gil;
|
||||||
int init_standard = 1, i = 0;
|
int init_standard = 1, i = 0;
|
||||||
#if PY_MAJOR_VERSION < 3
|
#if PY_MAJOR_VERSION < 3
|
||||||
|
|
@ -317,6 +317,7 @@ int pythonmod_init(struct module_env* env, int id)
|
||||||
if (py_mod_count==1) {
|
if (py_mod_count==1) {
|
||||||
/* Initialize Python */
|
/* Initialize Python */
|
||||||
if(PyRun_SimpleString("import sys \n") < 0 ) {
|
if(PyRun_SimpleString("import sys \n") < 0 ) {
|
||||||
|
log_err("pythonmod: cannot initialize core module: unboundmodule.py");
|
||||||
goto python_init_fail;
|
goto python_init_fail;
|
||||||
}
|
}
|
||||||
PyRun_SimpleString("sys.path.append('.') \n");
|
PyRun_SimpleString("sys.path.append('.') \n");
|
||||||
|
|
@ -329,13 +330,16 @@ int pythonmod_init(struct module_env* env, int id)
|
||||||
PyRun_SimpleString(wdir);
|
PyRun_SimpleString(wdir);
|
||||||
}
|
}
|
||||||
if(PyRun_SimpleString("import site\n") < 0) {
|
if(PyRun_SimpleString("import site\n") < 0) {
|
||||||
|
log_err("pythonmod: cannot initialize core module: unboundmodule.py");
|
||||||
goto python_init_fail;
|
goto python_init_fail;
|
||||||
}
|
}
|
||||||
if(PyRun_SimpleString("sys.path.extend(site.getsitepackages())\n") < 0) {
|
if(PyRun_SimpleString("sys.path.extend(site.getsitepackages())\n") < 0) {
|
||||||
|
log_err("pythonmod: cannot initialize core module: unboundmodule.py");
|
||||||
goto python_init_fail;
|
goto python_init_fail;
|
||||||
}
|
}
|
||||||
if(PyRun_SimpleString("from unboundmodule import *\n") < 0)
|
if(PyRun_SimpleString("from unboundmodule import *\n") < 0)
|
||||||
{
|
{
|
||||||
|
log_err("pythonmod: cannot initialize core module: unboundmodule.py");
|
||||||
goto python_init_fail;
|
goto python_init_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -352,18 +356,22 @@ int pythonmod_init(struct module_env* env, int id)
|
||||||
if (script_py == NULL)
|
if (script_py == NULL)
|
||||||
{
|
{
|
||||||
log_err("pythonmod: can't open file %s for reading", pe->fname);
|
log_err("pythonmod: can't open file %s for reading", pe->fname);
|
||||||
PyGILState_Release(gil);
|
goto python_init_fail;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load file */
|
/* Load file */
|
||||||
pe->module = PyImport_AddModule("__main__");
|
pe->module = PyImport_AddModule("__main__");
|
||||||
|
Py_XINCREF(pe->module);
|
||||||
pe->dict = PyModule_GetDict(pe->module);
|
pe->dict = PyModule_GetDict(pe->module);
|
||||||
|
Py_XINCREF(pe->dict);
|
||||||
pe->data = PyDict_New();
|
pe->data = PyDict_New();
|
||||||
Py_XINCREF(pe->data);
|
Py_XINCREF(pe->data); /* reference will be stolen below */
|
||||||
PyModule_AddObject(pe->module, "mod_env", pe->data);
|
if(PyModule_AddObject(pe->module, "mod_env", pe->data) < 0) {
|
||||||
|
log_err("pythonmod: could not add mod_env object");
|
||||||
/* TODO: deallocation of pe->... if an error occurs */
|
Py_XDECREF(pe->data); /* 2 times, here and on python_init_fail; */
|
||||||
|
/* on failure the reference is not stolen */
|
||||||
|
goto python_init_fail;
|
||||||
|
}
|
||||||
|
|
||||||
if (PyRun_SimpleFile(script_py, pe->fname) < 0) {
|
if (PyRun_SimpleFile(script_py, pe->fname) < 0) {
|
||||||
#if PY_MAJOR_VERSION <= 2 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 9)
|
#if PY_MAJOR_VERSION <= 2 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 9)
|
||||||
|
|
@ -394,18 +402,30 @@ int pythonmod_init(struct module_env* env, int id)
|
||||||
fstr = malloc(flen+1);
|
fstr = malloc(flen+1);
|
||||||
if(!fstr) {
|
if(!fstr) {
|
||||||
log_err("malloc failure to print parse error");
|
log_err("malloc failure to print parse error");
|
||||||
PyGILState_Release(gil);
|
|
||||||
|
/* close the file */
|
||||||
|
#if PY_MAJOR_VERSION < 3
|
||||||
|
Py_XDECREF(PyFileObject);
|
||||||
|
#else
|
||||||
fclose(script_py);
|
fclose(script_py);
|
||||||
return 0;
|
#endif
|
||||||
|
|
||||||
|
goto python_init_fail;
|
||||||
}
|
}
|
||||||
fseek(script_py, 0, SEEK_SET);
|
fseek(script_py, 0, SEEK_SET);
|
||||||
if(fread(fstr, flen, 1, script_py) < 1) {
|
if(fread(fstr, flen, 1, script_py) < 1) {
|
||||||
log_err("file read failed to print parse error: %s: %s",
|
log_err("file read failed to print parse error: %s: %s",
|
||||||
pe->fname, strerror(errno));
|
pe->fname, strerror(errno));
|
||||||
PyGILState_Release(gil);
|
|
||||||
fclose(script_py);
|
|
||||||
free(fstr);
|
free(fstr);
|
||||||
return 0;
|
|
||||||
|
/* close the file */
|
||||||
|
#if PY_MAJOR_VERSION < 3
|
||||||
|
Py_XDECREF(PyFileObject);
|
||||||
|
#else
|
||||||
|
fclose(script_py);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
goto python_init_fail;
|
||||||
}
|
}
|
||||||
fstr[flen] = 0;
|
fstr[flen] = 0;
|
||||||
/* we compile the string, but do not run it, to stop side-effects */
|
/* we compile the string, but do not run it, to stop side-effects */
|
||||||
|
|
@ -413,17 +433,26 @@ int pythonmod_init(struct module_env* env, int id)
|
||||||
* that we are expecting */
|
* that we are expecting */
|
||||||
(void)Py_CompileString(fstr, pe->fname, Py_file_input);
|
(void)Py_CompileString(fstr, pe->fname, Py_file_input);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
log_py_err();
|
log_py_err();
|
||||||
PyGILState_Release(gil);
|
|
||||||
|
/* close the file */
|
||||||
|
#if PY_MAJOR_VERSION < 3
|
||||||
|
Py_XDECREF(PyFileObject);
|
||||||
|
#else
|
||||||
fclose(script_py);
|
fclose(script_py);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION <= 2 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 9)
|
#if PY_MAJOR_VERSION <= 2 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 9)
|
||||||
/* no cleanup needed for python before 3.9 */
|
/* no cleanup needed for python before 3.9 */
|
||||||
#else
|
#else
|
||||||
/* cleanup for python 3.9 and newer */
|
/* cleanup for python 3.9 and newer */
|
||||||
free(fstr);
|
free(fstr);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
goto python_init_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* close the file */
|
||||||
#if PY_MAJOR_VERSION < 3
|
#if PY_MAJOR_VERSION < 3
|
||||||
Py_XDECREF(PyFileObject);
|
Py_XDECREF(PyFileObject);
|
||||||
#else
|
#else
|
||||||
|
|
@ -436,30 +465,26 @@ int pythonmod_init(struct module_env* env, int id)
|
||||||
if ((pe->func_init = PyDict_GetItemString(pe->dict, "init")) == NULL)
|
if ((pe->func_init = PyDict_GetItemString(pe->dict, "init")) == NULL)
|
||||||
{
|
{
|
||||||
log_err("pythonmod: function init is missing in %s", pe->fname);
|
log_err("pythonmod: function init is missing in %s", pe->fname);
|
||||||
PyGILState_Release(gil);
|
goto python_init_fail;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Py_XINCREF(pe->func_init);
|
Py_XINCREF(pe->func_init);
|
||||||
if ((pe->func_deinit = PyDict_GetItemString(pe->dict, "deinit")) == NULL)
|
if ((pe->func_deinit = PyDict_GetItemString(pe->dict, "deinit")) == NULL)
|
||||||
{
|
{
|
||||||
log_err("pythonmod: function deinit is missing in %s", pe->fname);
|
log_err("pythonmod: function deinit is missing in %s", pe->fname);
|
||||||
PyGILState_Release(gil);
|
goto python_init_fail;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
Py_XINCREF(pe->func_deinit);
|
Py_XINCREF(pe->func_deinit);
|
||||||
if ((pe->func_operate = PyDict_GetItemString(pe->dict, "operate")) == NULL)
|
if ((pe->func_operate = PyDict_GetItemString(pe->dict, "operate")) == NULL)
|
||||||
{
|
{
|
||||||
log_err("pythonmod: function operate is missing in %s", pe->fname);
|
log_err("pythonmod: function operate is missing in %s", pe->fname);
|
||||||
PyGILState_Release(gil);
|
goto python_init_fail;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
Py_XINCREF(pe->func_operate);
|
Py_XINCREF(pe->func_operate);
|
||||||
if ((pe->func_inform = PyDict_GetItemString(pe->dict, "inform_super")) == NULL)
|
if ((pe->func_inform = PyDict_GetItemString(pe->dict, "inform_super")) == NULL)
|
||||||
{
|
{
|
||||||
log_err("pythonmod: function inform_super is missing in %s", pe->fname);
|
log_err("pythonmod: function inform_super is missing in %s", pe->fname);
|
||||||
PyGILState_Release(gil);
|
goto python_init_fail;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
Py_XINCREF(pe->func_inform);
|
Py_XINCREF(pe->func_inform);
|
||||||
|
|
||||||
|
|
@ -477,20 +502,24 @@ int pythonmod_init(struct module_env* env, int id)
|
||||||
{
|
{
|
||||||
log_err("pythonmod: Exception occurred in function init");
|
log_err("pythonmod: Exception occurred in function init");
|
||||||
log_py_err();
|
log_py_err();
|
||||||
Py_XDECREF(res);
|
goto python_init_fail;
|
||||||
Py_XDECREF(py_init_arg);
|
|
||||||
PyGILState_Release(gil);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_XDECREF(res);
|
Py_XDECREF(res);
|
||||||
Py_XDECREF(py_init_arg);
|
Py_XDECREF(py_init_arg);
|
||||||
PyGILState_Release(gil);
|
PyGILState_Release(gil);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
python_init_fail:
|
python_init_fail:
|
||||||
log_err("pythonmod: cannot initialize core module: unboundmodule.py");
|
Py_XDECREF(pe->module);
|
||||||
|
Py_XDECREF(pe->dict);
|
||||||
|
Py_XDECREF(pe->data);
|
||||||
|
Py_XDECREF(pe->func_init);
|
||||||
|
Py_XDECREF(pe->func_deinit);
|
||||||
|
Py_XDECREF(pe->func_operate);
|
||||||
|
Py_XDECREF(pe->func_inform);
|
||||||
|
Py_XDECREF(res);
|
||||||
|
Py_XDECREF(py_init_arg);
|
||||||
PyGILState_Release(gil);
|
PyGILState_Release(gil);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -516,6 +545,8 @@ void pythonmod_deinit(struct module_env* env, int id)
|
||||||
/* Free result if any */
|
/* Free result if any */
|
||||||
Py_XDECREF(res);
|
Py_XDECREF(res);
|
||||||
/* Free shared data if any */
|
/* Free shared data if any */
|
||||||
|
Py_XDECREF(pe->module);
|
||||||
|
Py_XDECREF(pe->dict);
|
||||||
Py_XDECREF(pe->data);
|
Py_XDECREF(pe->data);
|
||||||
Py_XDECREF(pe->func_init);
|
Py_XDECREF(pe->func_init);
|
||||||
Py_XDECREF(pe->func_deinit);
|
Py_XDECREF(pe->func_deinit);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue