summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@suren.me>2016-02-23 09:03:22 +0100
committerSuren A. Chilingaryan <csa@suren.me>2016-02-23 09:03:22 +0100
commit3ea1907f3169e0233d3a32a7d470af3c34b6f967 (patch)
tree500cc0b4f4670807a73e9a1c2cc9359e2d5b3ba5
parent3f3b678b15eef0d102a021e07c8476b45e52940a (diff)
downloadpcitool-3ea1907f3169e0233d3a32a7d470af3c34b6f967.tar.gz
pcitool-3ea1907f3169e0233d3a32a7d470af3c34b6f967.tar.bz2
pcitool-3ea1907f3169e0233d3a32a7d470af3c34b6f967.tar.xz
pcitool-3ea1907f3169e0233d3a32a7d470af3c34b6f967.zip
Add more GILs to prevent Python crashes in multithreaded applications
-rw-r--r--pcilib/py.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/pcilib/py.c b/pcilib/py.c
index 1db18f7..a5118fb 100644
--- a/pcilib/py.c
+++ b/pcilib/py.c
@@ -276,10 +276,12 @@ pcilib_py_object *pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *va
#ifdef HAVE_PYTHON
int err = 0;
PyObject *res = NULL;
+ PyGILState_STATE gstate;
long ival;
double fval;
+ gstate = PyGILState_Ensure();
switch(val->type) {
case PCILIB_TYPE_LONG:
ival = pcilib_get_value_as_int(ctx, val, &err);
@@ -290,9 +292,12 @@ pcilib_py_object *pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *va
if (!err) res = (PyObject*)PyFloat_FromDouble(fval);
break;
default:
- err = PCILIB_ERROR_NOTSUPPORTED;
+ PyGILState_Release(gstate);
pcilib_error("Can't convert pcilib value of type (%lu) to PyObject", val->type);
+ if (ret) *ret = PCILIB_ERROR_NOTSUPPORTED;
+ return NULL;
}
+ PyGILState_Release(gstate);
if (err) {
if (ret) *ret = err;
@@ -314,7 +319,9 @@ int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py
#ifdef HAVE_PYTHON
int err = 0;
PyObject *pyval = (PyObject*)pval;
+ PyGILState_STATE gstate;
+ gstate = PyGILState_Ensure();
if (PyInt_Check(pyval)) {
err = pcilib_set_value_from_int(ctx, val, PyInt_AsLong(pyval));
} else if (PyFloat_Check(pyval)) {
@@ -322,10 +329,12 @@ int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py
} else if (PyString_Check(pyval)) {
err = pcilib_set_value_from_string(ctx, val, PyString_AsString(pyval));
} else {
+ PyGILState_Release(gstate);
pcilib_error("Can't convert PyObject to polymorphic pcilib value");
- err = PCILIB_ERROR_NOTSUPPORTED;
+ return PCILIB_ERROR_NOTSUPPORTED;
}
-
+ PyGILState_Release(gstate);
+
return err;
#else /* HAVE_PYTHON */
pcilib_error("Python is not supported");
@@ -443,6 +452,8 @@ static char *pcilib_py_parse_string(pcilib_t *ctx, const char *codestr, pcilib_v
int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value) {
#ifdef HAVE_PYTHON
+ int err;
+
PyGILState_STATE gstate;
char *code;
PyObject* obj;
@@ -463,7 +474,9 @@ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *va
}
pcilib_debug(VIEWS, "Evaluating a Python string \'%s\' to %lf=\'%s\'", codestr, PyFloat_AsDouble(obj), code);
- return pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj));
+ err = pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj));
+
+ return err;
#else /* HAVE_PYTHON */
pcilib_error("Current build not support python.");
return PCILIB_ERROR_NOTAVAILABLE;
@@ -489,20 +502,22 @@ int pcilib_py_eval_func(pcilib_t *ctx, const char *script_name, const char *func
if (err) return err;
}
+ PyGILState_STATE gstate = PyGILState_Ensure();
+
pyfunc = PyUnicode_FromString(func_name);
if (!pyfunc) {
if (pyval) Py_XDECREF(pyval);
+ PyGILState_Release(gstate);
return PCILIB_ERROR_MEMORY;
}
- PyGILState_STATE gstate = PyGILState_Ensure();
pyret = PyObject_CallMethodObjArgs(module->module, pyfunc, ctx->py->pcilib_pywrap, pyval, NULL);
- PyGILState_Release(gstate);
Py_XDECREF(pyfunc);
Py_XDECREF(pyval);
if (!pyret) {
+ PyGILState_Release(gstate);
pcilib_python_error("Error executing function (%s) of python script (%s)", func_name, script_name);
return PCILIB_ERROR_FAILED;
}
@@ -511,6 +526,7 @@ int pcilib_py_eval_func(pcilib_t *ctx, const char *script_name, const char *func
err = pcilib_set_value_from_pyobject(ctx, val, pyret);
Py_XDECREF(pyret);
+ PyGILState_Release(gstate);
return err;
#else /* HAVE_PYTHON */