From e652a69a69683eff0fed0ee53428f8bfb2443c70 Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Fri, 12 Mar 2010 12:44:44 +0000 Subject: [PATCH] Fix python if threaded. git-svn-id: file:///svn/unbound/trunk@2032 be551aaa-1e26-0410-a405-d3ace91eadb9 --- doc/Changelog | 1 + pythonmod/pythonmod.c | 41 +++++++++++++++++++++---------------- testdata/pymod_thread.tpkg | Bin 0 -> 4573 bytes 3 files changed, 24 insertions(+), 18 deletions(-) create mode 100644 testdata/pymod_thread.tpkg diff --git a/doc/Changelog b/doc/Changelog index 86d5581e9..94dfe00cb 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -3,6 +3,7 @@ earlier, and thus later checks benefit from and do not hinder them. - iana portlist updated. - ldns tarball updated. + - Fix python use when multithreaded. 11 March 2010: Wouter - another memory allocation option: --enable-alloc-nonregional. diff --git a/pythonmod/pythonmod.c b/pythonmod/pythonmod.c index 8d0a3fe9c..bfeb521d1 100644 --- a/pythonmod/pythonmod.c +++ b/pythonmod/pythonmod.c @@ -66,6 +66,8 @@ struct pythonmod_env { /** Python script filename. */ const char* fname; + /** Python main thread */ + PyThreadState* mainthr; /** Python module. */ PyObject* module; @@ -107,6 +109,7 @@ int pythonmod_init(struct module_env* env, int id) /* Initialize module */ FILE* script_py = NULL; PyObject* py_cfg, *res; + PyGILState_STATE gil; struct pythonmod_env* pe = (struct pythonmod_env*)calloc(1, sizeof(struct pythonmod_env)); if (!pe) { @@ -130,11 +133,11 @@ int pythonmod_init(struct module_env* env, int id) Py_NoSiteFlag = 1; Py_Initialize(); PyEval_InitThreads(); - PyEval_ReleaseLock(); SWIG_init(); + pe->mainthr = PyEval_SaveThread(); } - PyEval_AcquireLock(); + gil = PyGILState_Ensure(); /* Initialize Python */ PyRun_SimpleString("import sys \n"); @@ -150,7 +153,7 @@ int pythonmod_init(struct module_env* env, int id) if (PyRun_SimpleString("from unboundmodule import *\n") < 0) { log_err("pythonmod: cannot initialize core module: unboundmodule.py"); - PyEval_ReleaseLock(); + PyGILState_Release(gil); return 0; } @@ -158,7 +161,7 @@ int pythonmod_init(struct module_env* env, int id) if ((script_py = fopen(pe->fname, "r")) == NULL) { log_err("pythonmod: can't open file %s for reading", pe->fname); - PyEval_ReleaseLock(); + PyGILState_Release(gil); return 0; } @@ -174,7 +177,7 @@ int pythonmod_init(struct module_env* env, int id) if (PyRun_SimpleFile(script_py, pe->fname) < 0) { log_err("pythonmod: can't parse Python script %s", pe->fname); - PyEval_ReleaseLock(); + PyGILState_Release(gil); return 0; } @@ -183,25 +186,25 @@ int pythonmod_init(struct module_env* env, int id) if ((pe->func_init = PyDict_GetItemString(pe->dict, "init")) == NULL) { log_err("pythonmod: function init is missing in %s", pe->fname); - PyEval_ReleaseLock(); + PyGILState_Release(gil); return 0; } if ((pe->func_deinit = PyDict_GetItemString(pe->dict, "deinit")) == NULL) { log_err("pythonmod: function deinit is missing in %s", pe->fname); - PyEval_ReleaseLock(); + PyGILState_Release(gil); return 0; } if ((pe->func_operate = PyDict_GetItemString(pe->dict, "operate")) == NULL) { log_err("pythonmod: function operate is missing in %s", pe->fname); - PyEval_ReleaseLock(); + PyGILState_Release(gil); return 0; } if ((pe->func_inform = PyDict_GetItemString(pe->dict, "inform_super")) == NULL) { log_err("pythonmod: function inform_super is missing in %s", pe->fname); - PyEval_ReleaseLock(); + PyGILState_Release(gil); return 0; } @@ -215,7 +218,7 @@ int pythonmod_init(struct module_env* env, int id) Py_XDECREF(res); Py_XDECREF(py_cfg); - PyEval_ReleaseLock(); + PyGILState_Release(gil); return 1; } @@ -230,9 +233,9 @@ void pythonmod_deinit(struct module_env* env, int id) if(pe->module != NULL) { PyObject* res; + PyGILState_STATE gil = PyGILState_Ensure(); /* Deinit module */ - PyEval_AcquireLock(); res = PyObject_CallFunction(pe->func_deinit, "i", id); if (PyErr_Occurred()) { log_err("pythonmod: Exception occurred in function deinit"); @@ -242,8 +245,11 @@ void pythonmod_deinit(struct module_env* env, int id) Py_XDECREF(res); /* Free shared data if any */ Py_XDECREF(pe->data); + PyGILState_Release(gil); + PyEval_RestoreThread(pe->mainthr); Py_Finalize(); + pe->mainthr = NULL; } pe->fname = NULL; free(pe); @@ -257,6 +263,7 @@ void pythonmod_inform_super(struct module_qstate* qstate, int id, struct module_ struct pythonmod_env* pe = (struct pythonmod_env*)qstate->env->modinfo[id]; struct pythonmod_qstate* pq = (struct pythonmod_qstate*)qstate->minfo[id]; PyObject* py_qstate, *py_sqstate, *res; + PyGILState_STATE gil = PyGILState_Ensure(); log_query_info(VERB_ALGO, "pythonmod: inform_super, sub is", &qstate->qinfo); log_query_info(VERB_ALGO, "super is", &super->qinfo); @@ -264,7 +271,6 @@ void pythonmod_inform_super(struct module_qstate* qstate, int id, struct module_ py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0); py_sqstate = SWIG_NewPointerObj((void*) super, SWIGTYPE_p_module_qstate, 0); - PyEval_AcquireLock(); res = PyObject_CallFunction(pe->func_inform, "iOOO", id, py_qstate, py_sqstate, pq->data); @@ -284,7 +290,7 @@ void pythonmod_inform_super(struct module_qstate* qstate, int id, struct module_ Py_XDECREF(py_sqstate); Py_XDECREF(py_qstate); - PyEval_ReleaseLock(); + PyGILState_Release(gil); } void pythonmod_operate(struct module_qstate* qstate, enum module_ev event, @@ -293,6 +299,7 @@ void pythonmod_operate(struct module_qstate* qstate, enum module_ev event, struct pythonmod_env* pe = (struct pythonmod_env*)qstate->env->modinfo[id]; struct pythonmod_qstate* pq = (struct pythonmod_qstate*)qstate->minfo[id]; PyObject* py_qstate, *res; + PyGILState_STATE gil = PyGILState_Ensure(); if ( pq == NULL) { @@ -304,9 +311,6 @@ void pythonmod_operate(struct module_qstate* qstate, enum module_ev event, Py_INCREF(pq->data); } - /* Lock Python */ - PyEval_AcquireLock(); - /* Call operate */ py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0); res = PyObject_CallFunction(pe->func_operate, "iiOO", id, (int) event, @@ -325,8 +329,7 @@ void pythonmod_operate(struct module_qstate* qstate, enum module_ev event, Py_XDECREF(res); Py_XDECREF(py_qstate); - /* Unlock Python */ - PyEval_ReleaseLock(); + PyGILState_Release(gil); } void pythonmod_clear(struct module_qstate* qstate, int id) @@ -340,7 +343,9 @@ void pythonmod_clear(struct module_qstate* qstate, int id) (unsigned long int)pq); if(pq != NULL) { + PyGILState_STATE gil = PyGILState_Ensure(); Py_DECREF(pq->data); + PyGILState_Release(gil); /* Free qstate */ free(pq); } diff --git a/testdata/pymod_thread.tpkg b/testdata/pymod_thread.tpkg new file mode 100644 index 0000000000000000000000000000000000000000..58aebceb4ac422a00664e9dd19559aa9bc328ad3 GIT binary patch literal 4573 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