summaryrefslogtreecommitdiffstats
path: root/pcilib/py.c
diff options
context:
space:
mode:
authorVasilii Chernov <vchernov@inr.ru>2016-03-01 10:42:40 +0100
committerVasilii Chernov <vchernov@inr.ru>2016-03-01 10:42:40 +0100
commit5d775d64bdec554b9842823bd1c46263210425fd (patch)
treecb1da12066687273f7dccace7aba4ee1ff2ba25c /pcilib/py.c
parent0e584d07a0776454fd5487b7d23407c0624b56c2 (diff)
downloadpcitool-5d775d64bdec554b9842823bd1c46263210425fd.tar.gz
pcitool-5d775d64bdec554b9842823bd1c46263210425fd.tar.bz2
pcitool-5d775d64bdec554b9842823bd1c46263210425fd.tar.xz
pcitool-5d775d64bdec554b9842823bd1c46263210425fd.zip
1. multithreading:
- Enable multiprocessing for api_server - Enable mutrithreading for html_server 2. py: - extract pcilib->py bases from pcilib->py functions - add api for interact directly with pcilib->py without pcilib context. 3. pcipywrap - Add scripts handling.
Diffstat (limited to 'pcilib/py.c')
-rw-r--r--pcilib/py.c309
1 files changed, 224 insertions, 85 deletions
diff --git a/pcilib/py.c b/pcilib/py.c
index 6cf9fdc..934c11f 100644
--- a/pcilib/py.c
+++ b/pcilib/py.c
@@ -89,8 +89,6 @@ void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flag
#endif /* HAVE_PYTHON */
}
-
-
int pcilib_init_py(pcilib_t *ctx) {
#ifdef HAVE_PYTHON
ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t));
@@ -143,8 +141,6 @@ int pcilib_init_py(pcilib_t *ctx) {
int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) {
#ifdef HAVE_PYTHON
int err = 0;
- PyObject *pypath, *pynewdir;
- PyObject *pydict, *pystr, *pyret = NULL;
char *script_dir;
const char *model_dir = getenv("PCILIB_MODEL_DIR");
@@ -160,83 +156,59 @@ int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) {
sprintf(script_dir, "%s/%s", model_dir, dir);
}
- pypath = PySys_GetObject("path");
- if (!pypath) {
- pcilib_python_error("Can't get python path");
- return PCILIB_ERROR_FAILED;
- }
+ err = pcilib_py_ctx_add_script_dir(ctx->py, script_dir);
+ if(err) return err;
+#endif /* HAVE_PYTHON */
- pynewdir = PyString_FromString(script_dir);
- if (!pynewdir) {
- pcilib_python_error("Can't create python string");
- return PCILIB_ERROR_MEMORY;
+ return 0;
+}
+
+void pcilib_py_free_hash(pcilib_py_t *ctx_py) {
+ if (ctx_py->script_hash) {
+ pcilib_script_t *script, *script_tmp;
+
+ HASH_ITER(hh, ctx_py->script_hash, script, script_tmp) {
+ Py_DECREF(script->module);
+ HASH_DEL(ctx_py->script_hash, script);
+ free(script);
+ }
+ ctx_py->script_hash = NULL;
}
-
- // Checking if the directory already in the path
- pydict = PyDict_New();
- if (pydict) {
- pystr = PyString_FromString("cur");
- if (pystr) {
- PyDict_SetItem(pydict, pystr, pynewdir);
- Py_DECREF(pystr);
- }
+}
- pystr = PyString_FromString("path");
- if (pystr) {
- PyDict_SetItem(pydict, pystr, pypath);
- Py_DECREF(pystr);
- }
+void pcilib_free_py_ctx(pcilib_py_t *ctx_py) {
+#ifdef HAVE_PYTHON
+ int finalyze = 0;
- pyret = PyRun_String("cur in path", Py_eval_input, ctx->py->global_dict, pydict);
- Py_DECREF(pydict);
- }
+ if (ctx_py) {
+ if (ctx_py->finalyze) finalyze = 1;
- if ((pyret == Py_False)&&(PyList_Append(pypath, pynewdir) == -1))
- err = PCILIB_ERROR_FAILED;
+ pcilib_py_free_hash(ctx_py);
- if (pyret) Py_DECREF(pyret);
- Py_DECREF(pynewdir);
+ if (ctx_py->pcilib_pywrap)
+ Py_DECREF(ctx_py->pcilib_pywrap);
- if (err) {
- pcilib_python_error("Can't add directory (%s) to python path", script_dir);
- return err;
- }
-#endif /* HAVE_PYTHON */
+ free(ctx_py);
+ }
- return 0;
+ if (finalyze)
+ Py_Finalize();
+#endif /* HAVE_PYTHON */
}
+
void pcilib_free_py(pcilib_t *ctx) {
#ifdef HAVE_PYTHON
- int finalyze = 0;
-
- if (ctx->py) {
- if (ctx->py->finalyze) finalyze = 1;
-
- if (ctx->py->script_hash) {
- pcilib_script_t *script, *script_tmp;
-
- HASH_ITER(hh, ctx->py->script_hash, script, script_tmp) {
- Py_DECREF(script->module);
- HASH_DEL(ctx->py->script_hash, script);
- free(script);
- }
- ctx->py->script_hash = NULL;
- }
-
- if (ctx->py->pcilib_pywrap)
- Py_DECREF(ctx->py->pcilib_pywrap);
-
- free(ctx->py);
- ctx->py = NULL;
- }
-
- if (finalyze)
- Py_Finalize();
+ pcilib_free_py_ctx(ctx->py);
+ ctx->py = NULL;
#endif /* HAVE_PYTHON */
}
int pcilib_py_load_script(pcilib_t *ctx, const char *script_name) {
+ return pcilib_py_ctx_load_script(ctx->py, script_name);
+}
+
+int pcilib_py_ctx_load_script(pcilib_py_t *ctx_py, const char *script_name) {
#ifdef HAVE_PYTHON
PyObject* pymodule;
pcilib_script_t *module = NULL;
@@ -252,7 +224,7 @@ int pcilib_py_load_script(pcilib_t *ctx, const char *script_name) {
}
*py = 0;
- HASH_FIND_STR(ctx->py->script_hash, script_name, module);
+ HASH_FIND_STR(ctx_py->script_hash, script_name, module);
if (module) return 0;
pymodule = PyImport_ImportModule(module_name);
@@ -266,7 +238,7 @@ int pcilib_py_load_script(pcilib_t *ctx, const char *script_name) {
module->module = pymodule;
module->name = script_name;
- HASH_ADD_KEYPTR(hh, ctx->py->script_hash, module->name, strlen(module->name), module);
+ HASH_ADD_STR(ctx_py->script_hash, name, module);
#endif /* HAVE_PYTHON */
return 0;
}
@@ -527,51 +499,218 @@ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *va
int pcilib_py_eval_func(pcilib_t *ctx, const char *script_name, const char *func_name, pcilib_value_t *val) {
#ifdef HAVE_PYTHON
int err = 0;
+ PyObject *pyval = NULL;
+
+ if (val) {
+ pyval = pcilib_get_value_as_pyobject(ctx, val, &err);
+ if (err) return err;
+ }
+
+ PyObject* pyret = pcilib_py_ctx_eval_func(ctx->py, script_name,
+ func_name, pyval, &err);
+ if (err) return err;
+
+ if ((val)&&(pyret != Py_None))
+ err = pcilib_set_value_from_pyobject(ctx, val, pyret);
+
+ Py_DECREF(pyret);
+
+ return err;
+#else /* HAVE_PYTHON */
+ pcilib_error("Python is not supported");
+ return PCILIB_ERROR_NOTSUPPORTED;
+#endif /* HAVE_PYTHON */
+}
+
+pcilib_py_object* pcilib_py_ctx_eval_func(pcilib_py_t *ctx_py,
+ const char *script_name,
+ const char *func_name,
+ pcilib_py_object *pyval,
+ int *err) {
+#ifdef HAVE_PYTHON
PyObject *pyfunc;
- PyObject *pyval = NULL, *pyret;
+ PyObject *pyret;
pcilib_script_t *module = NULL;
- HASH_FIND_STR(ctx->py->script_hash, script_name, module);
+ HASH_FIND_STR(ctx_py->script_hash, script_name, module);
if (!module) {
pcilib_error("Script (%s) is not loaded", script_name);
- return PCILIB_ERROR_NOTFOUND;
- }
-
- if (val) {
- pyval = pcilib_get_value_as_pyobject(ctx, val, &err);
- if (err) return err;
+ if(err) *err = PCILIB_ERROR_NOTFOUND;
+ return NULL;
}
-
+
PyGILState_STATE gstate = PyGILState_Ensure();
pyfunc = PyUnicode_FromString(func_name);
if (!pyfunc) {
if (pyval) Py_DECREF(pyval);
PyGILState_Release(gstate);
- return PCILIB_ERROR_MEMORY;
+ if(err) *err = PCILIB_ERROR_MEMORY;
+ return NULL;
}
- pyret = PyObject_CallMethodObjArgs(module->module, pyfunc, ctx->py->pcilib_pywrap, pyval, NULL);
+ pyret = PyObject_CallMethodObjArgs(module->module,
+ pyfunc,
+ ctx_py->pcilib_pywrap,
+ pyval,
+ NULL);
Py_DECREF(pyfunc);
Py_DECREF(pyval);
-
+
if (!pyret) {
PyGILState_Release(gstate);
- pcilib_python_error("Error executing function (%s) of python script (%s)", func_name, script_name);
+ pcilib_python_error("Error executing function (%s) of python "
+ "script (%s)", func_name, script_name);
+ if(err) *err = PCILIB_ERROR_FAILED;
+ return NULL;
+ }
+ PyGILState_Release(gstate);
+
+ return pyret;
+
+#else /* HAVE_PYTHON */
+ pcilib_error("Python is not supported");
+ if(err) *err = PCILIB_ERROR_NOTSUPPORTED;
+ return NULL;
+#endif /* HAVE_PYTHON */
+}
+
+int pcilib_py_ctx_add_script_dir(pcilib_py_t *ctx_py, const char *dir) {
+#ifdef HAVE_PYTHON
+ int err = 0;
+ PyObject *pypath, *pynewdir;
+ PyObject *pydict, *pystr, *pyret = NULL;
+
+ //const char *model_dir = getenv("PCILIB_MODEL_DIR");
+ //if (!model_dir) model_dir = PCILIB_MODEL_DIR;
+
+ pypath = PySys_GetObject("path");
+ if (!pypath) {
+ pcilib_python_error("Can't get python path");
return PCILIB_ERROR_FAILED;
}
- if ((val)&&(pyret != Py_None))
- err = pcilib_set_value_from_pyobject(ctx, val, pyret);
+ pynewdir = PyString_FromString(dir);
+ if (!pynewdir) {
+ pcilib_python_error("Can't create python string");
+ return PCILIB_ERROR_MEMORY;
+ }
- Py_DECREF(pyret);
- PyGILState_Release(gstate);
+ // Checking if the directory already in the path
+ pydict = PyDict_New();
+ if (pydict) {
+ pystr = PyString_FromString("cur");
+ if (pystr) {
+ PyDict_SetItem(pydict, pystr, pynewdir);
+ Py_DECREF(pystr);
+ } else {
+ pcilib_python_error("Can't create python string");
+ return PCILIB_ERROR_MEMORY;
+ }
- return err;
+ pystr = PyString_FromString("path");
+ if (pystr) {
+ PyDict_SetItem(pydict, pystr, pypath);
+ Py_DECREF(pystr);
+ } else {
+ pcilib_python_error("Can't create python string");
+ return PCILIB_ERROR_MEMORY;
+ }
+
+ pyret = PyRun_String("cur in path", Py_eval_input, ctx_py->global_dict, pydict);
+ Py_DECREF(pydict);
+
+ } else {
+ pcilib_python_error("Can't create python dict");
+ return PCILIB_ERROR_MEMORY;
+ }
+
+ if ((pyret == Py_False)&&(PyList_Append(pypath, pynewdir) == -1))
+ err = PCILIB_ERROR_FAILED;
+
+ if (pyret) Py_DECREF(pyret);
+ Py_DECREF(pynewdir);
+
+ if (err) {
+ pcilib_python_error("Can't add directory (%s) to python path", dir);
+ return err;
+ }
+ return 0;
#else /* HAVE_PYTHON */
pcilib_error("Python is not supported");
return PCILIB_ERROR_NOTSUPPORTED;
#endif /* HAVE_PYTHON */
}
+
+pcilib_py_t* pcilib_init_py_ctx(pcilib_py_t* in, int *err) {
+ pcilib_py_t* out = (pcilib_py_t*)malloc(sizeof(pcilib_py_t));
+ if (!out) {
+ if(err) *err = PCILIB_ERROR_MEMORY;
+ return NULL;
+ }
+
+ out->finalyze = 0;
+ out->main_module = in->main_module;
+ out->global_dict = in->global_dict;
+ out->pcilib_pywrap = in->pcilib_pywrap;
+ out->script_hash = NULL;
+
+ if(err) *err = 0;
+ return out;
+}
+
+/*!
+ * \brief Wrap for PyDict_SetItem, with decrease reference counting after set.
+ */
+void pcilib_pydict_set_item(pcilib_py_object* dict, pcilib_py_object* name, pcilib_py_object* value)
+{
+ PyDict_SetItem(dict,
+ name,
+ value);
+ Py_XDECREF(name);
+ Py_XDECREF(value);
+}
+
+/*!
+ * \brief Wrap for PyList_Append, with decrease reference counting after append.
+ */
+void pcilib_pylist_append(pcilib_py_object* list, pcilib_py_object* value)
+{
+ PyList_Append(list, value);
+ Py_XDECREF(value);
+}
+
+pcilib_py_object *pcilib_py_ctx_get_scripts_info(pcilib_py_t *ctx_py) {
+
+ PyObject* pyList = PyList_New(0);
+
+ if (ctx_py->script_hash) {
+ pcilib_script_t *script, *script_tmp;
+
+ HASH_ITER(hh, ctx_py->script_hash, script, script_tmp) {
+
+ PyObject* pylistItem = PyDict_New();
+ pcilib_pydict_set_item(pylistItem,
+ PyString_FromString("name"),
+ PyString_FromString(script->name));
+
+ PyObject* dict = PyModule_GetDict(script->module);
+ if (dict) {
+ PyObject* pystr = PyString_FromString("description");
+ if (pystr) {
+ if (PyDict_Contains(dict, pystr)) {
+ PyDict_SetItem(pylistItem,
+ pystr,
+ PyDict_GetItem(dict, pystr));
+ }
+ Py_DECREF(pystr);
+ }
+ }
+ pcilib_pylist_append(pyList, pylistItem);
+
+ }
+ }
+ return pyList;
+}