diff options
author | Vasilii Chernov <vchernov@inr.ru> | 2016-03-01 10:42:40 +0100 |
---|---|---|
committer | Vasilii Chernov <vchernov@inr.ru> | 2016-03-01 10:42:40 +0100 |
commit | 5d775d64bdec554b9842823bd1c46263210425fd (patch) | |
tree | cb1da12066687273f7dccace7aba4ee1ff2ba25c /pcilib/py.c | |
parent | 0e584d07a0776454fd5487b7d23407c0624b56c2 (diff) | |
download | pcitool-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.c | 309 |
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; +} |