From 5349163e93a107fdfea2ad58760f6149a8d749b0 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Fri, 5 Feb 2016 12:33:48 +0100 Subject: Add support for python script properties. Correct pcilib python wrapping. Update examples. Update cmakelists for work in shadow build mode. --- pcilib/py.c | 1 - 1 file changed, 1 deletion(-) (limited to 'pcilib/py.c') diff --git a/pcilib/py.c b/pcilib/py.c index 4256afc..13113d7 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -5,7 +5,6 @@ #include #include - #include "pci.h" #include "debug.h" #include "pcilib.h" -- cgit v1.2.3 From d9a31945a92a76e590657dc2e65bb20b6ea95d90 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Thu, 11 Feb 2016 10:37:24 +0100 Subject: Merge script and transform view. Add get register and properties info to python wrap. --- pcilib/py.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 183 insertions(+), 4 deletions(-) (limited to 'pcilib/py.c') diff --git a/pcilib/py.c b/pcilib/py.c index 13113d7..20b85a1 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -16,11 +16,18 @@ struct pcilib_py_s { PyObject *global_dict; }; +struct pcilib_script_s { + PyObject *py_script_module; /**< PyModule object, contains script enviroment */ + PyObject *dict; + char* script_name; +}; + int pcilib_init_py(pcilib_t *ctx) { ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t)); if (!ctx->py) return PCILIB_ERROR_MEMORY; - Py_Initialize(); + if(!Py_IsInitialized()) + Py_Initialize(); ctx->py->main_module = PyImport_AddModule("__parser__"); if (!ctx->py->main_module) @@ -35,12 +42,11 @@ int pcilib_init_py(pcilib_t *ctx) { void pcilib_free_py(pcilib_t *ctx) { if (ctx->py) { - // Dict and module references are borrowed + // Dict and module references are borrowed free(ctx->py); ctx->py = NULL; } - - Py_Finalize(); + //Py_Finalize(); } /* @@ -189,3 +195,176 @@ 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)); } + + +int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **module, pcilib_access_mode_t *mode) +{ + int err; + + //Initialize python script, if it has not initialized already. + if(!module_name) + { + pcilib_error("Invalid script name specified in XML property (NULL)"); + return PCILIB_ERROR_INVALID_DATA; + } + + //create path string to scripts + char* model_dir = getenv("PCILIB_MODEL_DIR"); + char* model_path = malloc(strlen(model_dir) + strlen(ctx->model) + 2); + if (!model_path) return PCILIB_ERROR_MEMORY; + sprintf(model_path, "%s/%s", model_dir, ctx->model); + + //set model path to python + PySys_SetPath(model_path); + free(model_path); + model_path = NULL; + + //create path string to pcipywrap library + char* app_dir = getenv("APP_PATH"); + char* pcipywrap_path; + if(app_dir) + { + pcipywrap_path = malloc(strlen(app_dir) + strlen("/pcilib")); + if (!pcipywrap_path) return PCILIB_ERROR_MEMORY; + sprintf(pcipywrap_path, "%s/%s", "/pcilib", ctx->model); + } + else + { + pcipywrap_path = malloc(strlen("./pcilib")); + if (!pcipywrap_path) return PCILIB_ERROR_MEMORY; + sprintf(pcipywrap_path, "%s", "./pcilib"); + + } + + //set pcipywrap library path to python + PyObject* path = PySys_GetObject("path"); + if(PyList_Append(path, PyString_FromString(pcipywrap_path)) == -1) + { + pcilib_error("Cant set pcipywrap library path to python."); + return PCILIB_ERROR_FAILED; + } + free(pcipywrap_path); + pcipywrap_path = NULL; + + + //extract module name from script name + char* py_module_name = strtok(module_name, "."); + + if(!py_module_name) + { + pcilib_error("Invalid script name specified in XML property (%s)." + " Seems like name doesnt contains extension", module_name); + return PCILIB_ERROR_INVALID_DATA; + } + + //import python script + PyObject* py_script_module = PyImport_ImportModule(py_module_name); + + if(!py_script_module) + { + printf("Error in import python module: "); + PyErr_Print(); + return PCILIB_ERROR_INVALID_DATA; + } + + + //Initializing pcipywrap module if script use it + PyObject* dict = PyModule_GetDict(py_script_module); + if(PyDict_Contains(dict, PyString_FromString("pcipywrap"))) + { + PyObject* pcipywrap_module = PyDict_GetItemString(dict, "pcipywrap"); + if(!pcipywrap_module) + { + pcilib_error("Cant extract pcipywrap module from script dictionary"); + return PCILIB_ERROR_FAILED; + } + + //setting pcilib_t instance + PyObject_CallMethodObjArgs(pcipywrap_module, + PyUnicode_FromString("setPcilib"), + PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*)), + NULL); + } + + //Success. Create struct and initialize values + module[0] = (pcilib_script_t*)malloc(sizeof(pcilib_script_t)); + module[0]->py_script_module = py_script_module; + module[0]->script_name = module_name; + module[0]->dict = dict; + + //Setting correct mode + mode[0] = 0; + if(PyDict_Contains(dict, PyString_FromString("read_from_register"))) + mode[0] |= PCILIB_ACCESS_R; + if(PyDict_Contains(dict, PyString_FromString("write_to_register"))) + mode[0] |= PCILIB_ACCESS_W; + + return 0; +} + +int pcilib_free_py_script(pcilib_script_t *module) +{ + if(module) + { + if(module->script_name) + { + free(module->script_name); + module->script_name = NULL; + } + + if(module->py_script_module) + { + //PyObject_Free(module->py_script_module); + module->py_script_module = NULL; + } + } +} + +int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val) +{ + + int err; + + PyObject *ret = PyObject_CallMethod(module->py_script_module, "read_from_register", "()"); + if (!ret) + { + printf("Python script error: "); + PyErr_Print(); + return PCILIB_ERROR_FAILED; + } + + err = pcilib_convert_pyobject_to_val(ctx, ret, val); + + if(err) + { + pcilib_error("Failed to convert python script return value to internal type: %i", err); + return err; + } + return 0; +} + +int pcilib_script_write(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val) +{ + int err; + + PyObject *input = pcilib_convert_val_to_pyobject(ctx, val, printf); + if(!input) + { + printf("Failed to convert input value to Python object"); + PyErr_Print(); + return PCILIB_ERROR_FAILED; + } + + PyObject *ret = PyObject_CallMethodObjArgs(module->py_script_module, + PyUnicode_FromString("write_to_register"), + input, + NULL); + if (!ret) + { + printf("Python script error: "); + PyErr_Print(); + return PCILIB_ERROR_FAILED; + } + + return 0; +} -- cgit v1.2.3 From f526c4a5a3e4f35bb1c4b03af1f3244a8c0db48a Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Thu, 11 Feb 2016 12:00:54 +0100 Subject: Change error logging method in Python wrap. Move functions, that converts values between PyObject and pcilib_value_t to py.c --- pcilib/py.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) (limited to 'pcilib/py.c') diff --git a/pcilib/py.c b/pcilib/py.c index 20b85a1..acc18df 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -196,6 +196,77 @@ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *va return pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj)); } +void* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val) +{ + int err; + + switch(val->type) + { + case PCILIB_TYPE_INVALID: + pcilib_error("Invalid register output type (PCILIB_TYPE_INVALID)"); + return NULL; + + case PCILIB_TYPE_STRING: + pcilib_error("Invalid register output type (PCILIB_TYPE_STRING)"); + return NULL; + + case PCILIB_TYPE_LONG: + { + long ret; + ret = pcilib_get_value_as_int(ctx, val, &err); + + if(err) + { + pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); + return NULL; + } + return (PyObject*)PyInt_FromLong((long) ret); + } + + case PCILIB_TYPE_DOUBLE: + { + double ret; + ret = pcilib_get_value_as_float(ctx, val, &err); + + if(err) + { + pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); + return NULL; + } + return (PyObject*)PyFloat_FromDouble((double) ret); + } + + default: + pcilib_error("Invalid register output type (unknown)"); + return NULL; + } +} + +int pcilib_convert_pyobject_to_val(pcilib_t* ctx, void* pyObjVal, pcilib_value_t *val) +{ + PyObject* pyVal = pyObjVal; + int err; + + if(PyInt_Check(pyVal)) + { + err = pcilib_set_value_from_int(ctx, val, PyInt_AsLong(pyVal)); + } + else + if(PyFloat_Check(pyVal)) + err = pcilib_set_value_from_float(ctx, val, PyFloat_AsDouble(pyVal)); + else + if(PyString_Check(pyVal)) + err = pcilib_set_value_from_static_string(ctx, val, PyString_AsString(pyVal)); + else + { + pcilib_error("Invalid input. Input type should be int, float or string."); + return PCILIB_ERROR_NOTSUPPORTED; + } + if(err) + return err; + + return 0; +} int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **module, pcilib_access_mode_t *mode) { @@ -347,7 +418,7 @@ int pcilib_script_write(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t * { int err; - PyObject *input = pcilib_convert_val_to_pyobject(ctx, val, printf); + PyObject *input = pcilib_convert_val_to_pyobject(ctx, val); if(!input) { printf("Failed to convert input value to Python object"); -- cgit v1.2.3 From 76ee5a167add1c169a982ab59aa0544f827cb365 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Thu, 11 Feb 2016 12:28:37 +0100 Subject: Solve errors in serialing register_info function. Clear unused code --- pcilib/py.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'pcilib/py.c') diff --git a/pcilib/py.c b/pcilib/py.c index acc18df..57a5f46 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -269,9 +269,7 @@ int pcilib_convert_pyobject_to_val(pcilib_t* ctx, void* pyObjVal, pcilib_value_t } int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **module, pcilib_access_mode_t *mode) -{ - int err; - +{ //Initialize python script, if it has not initialized already. if(!module_name) { @@ -389,6 +387,8 @@ int pcilib_free_py_script(pcilib_script_t *module) module->py_script_module = NULL; } } + + return 0; } int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val) @@ -415,9 +415,7 @@ int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *v } int pcilib_script_write(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val) -{ - int err; - +{ PyObject *input = pcilib_convert_val_to_pyobject(ctx, val); if(!input) { -- cgit v1.2.3 From d7fc669bf0dbe37f46d2efec4940feb8504017c2 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Thu, 11 Feb 2016 14:24:01 +0100 Subject: Change no_set_check parameter name. Move Python wrap to separate directory. --- pcilib/py.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'pcilib/py.c') diff --git a/pcilib/py.c b/pcilib/py.c index 57a5f46..664e170 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -293,15 +293,15 @@ int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **mo char* pcipywrap_path; if(app_dir) { - pcipywrap_path = malloc(strlen(app_dir) + strlen("/pcilib")); + pcipywrap_path = malloc(strlen(app_dir) + strlen("/pywrap")); if (!pcipywrap_path) return PCILIB_ERROR_MEMORY; - sprintf(pcipywrap_path, "%s/%s", "/pcilib", ctx->model); + sprintf(pcipywrap_path, "%s/%s", "/pywrap", ctx->model); } else { - pcipywrap_path = malloc(strlen("./pcilib")); + pcipywrap_path = malloc(strlen("./pywrap")); if (!pcipywrap_path) return PCILIB_ERROR_MEMORY; - sprintf(pcipywrap_path, "%s", "./pcilib"); + sprintf(pcipywrap_path, "%s", "./pywrap"); } -- cgit v1.2.3 From 55eab7196d0104c71e40136b3b22e9501d234e17 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Fri, 12 Feb 2016 14:43:20 +0100 Subject: 1. Cmakelists - move copy xml folder command to root file 2. - Move set python paths code to python module init funtction - pci.c move python module init block code after checking model to get paths before it runs. - Fix set python path code to work with PYTHONPATH - Update pci run script to work with PYTHONPATH - Fix python finalize code 3. Change pcilib_script_s interacting method. Now it stores in hash. 4. Change names of some fucntions to more unified ones 5. Remove old unused function pcilib_xml_create_script_or_transform_view 6. cli - disable reading register after set if write_verification flag is off 7. Remove uninformative error messages fro Python wrap. 8. - Server.py - add read/write property/register command handling - Add help message - Correcting paths --- pcilib/py.c | 194 ++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 117 insertions(+), 77 deletions(-) (limited to 'pcilib/py.c') diff --git a/pcilib/py.c b/pcilib/py.c index 664e170..7b1ae79 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -11,24 +11,37 @@ #include "py.h" #include "error.h" + + struct pcilib_py_s { PyObject *main_module; PyObject *global_dict; + int py_initialized_inside; ///< Flag, shows that Py_Initialize has been called inside class }; -struct pcilib_script_s { +typedef struct pcilib_script_s { + char* script_name; PyObject *py_script_module; /**< PyModule object, contains script enviroment */ PyObject *dict; - char* script_name; -}; + pcilib_access_mode_t mode; + + UT_hash_handle hh; +} pcilib_script_s; + +struct pcilib_script_s *scripts = NULL; int pcilib_init_py(pcilib_t *ctx) { ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t)); if (!ctx->py) return PCILIB_ERROR_MEMORY; if(!Py_IsInitialized()) + { Py_Initialize(); - + ctx->py->py_initialized_inside = 1; + } + else + ctx->py->py_initialized_inside = 0; + ctx->py->main_module = PyImport_AddModule("__parser__"); if (!ctx->py->main_module) return PCILIB_ERROR_FAILED; @@ -36,17 +49,45 @@ int pcilib_init_py(pcilib_t *ctx) { ctx->py->global_dict = PyModule_GetDict(ctx->py->main_module); if (!ctx->py->global_dict) return PCILIB_ERROR_FAILED; - + + + //create path string, where the model scripts should be + static int model_dir_added = 0; + if(!model_dir_added) + { + char* model_dir = getenv("PCILIB_MODEL_DIR"); + char* model_path = malloc(strlen(model_dir) + strlen(ctx->model) + 2); + if (!model_path) return PCILIB_ERROR_MEMORY; + sprintf(model_path, "%s/%s", model_dir, ctx->model); + //add path to python + PyObject* path = PySys_GetObject("path"); + if(PyList_Append(path, PyString_FromString(model_path)) == -1) + { + pcilib_error("Cant set PCILIB_MODEL_DIR library path to python."); + free(model_path); + return PCILIB_ERROR_FAILED; + } + free(model_path); + model_dir_added = 1; + } return 0; } void pcilib_free_py(pcilib_t *ctx) { - if (ctx->py) { + + int py_initialized_inside = 0; + + if (ctx->py) { + if(ctx->py->py_initialized_inside) + py_initialized_inside = 1; + // Dict and module references are borrowed free(ctx->py); ctx->py = NULL; } - //Py_Finalize(); + + if(py_initialized_inside) + Py_Finalize(); } /* @@ -196,7 +237,7 @@ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *va return pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj)); } -void* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val) +void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val) { int err; @@ -242,7 +283,7 @@ void* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val) } } -int pcilib_convert_pyobject_to_val(pcilib_t* ctx, void* pyObjVal, pcilib_value_t *val) +int pcilib_set_value_from_pyobject(pcilib_t* ctx, void* pyObjVal, pcilib_value_t *val) { PyObject* pyVal = pyObjVal; int err; @@ -268,61 +309,30 @@ int pcilib_convert_pyobject_to_val(pcilib_t* ctx, void* pyObjVal, pcilib_value_t return 0; } -int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **module, pcilib_access_mode_t *mode) +int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t *mode) { - //Initialize python script, if it has not initialized already. - if(!module_name) + //extract module name from script name + char* py_module_name = strtok(module_name, "."); + if(!py_module_name) { - pcilib_error("Invalid script name specified in XML property (NULL)"); + pcilib_error("Invalid script name specified in XML property (%s)." + " Seems like name doesnt contains extension", module_name); return PCILIB_ERROR_INVALID_DATA; } - //create path string to scripts - char* model_dir = getenv("PCILIB_MODEL_DIR"); - char* model_path = malloc(strlen(model_dir) + strlen(ctx->model) + 2); - if (!model_path) return PCILIB_ERROR_MEMORY; - sprintf(model_path, "%s/%s", model_dir, ctx->model); - - //set model path to python - PySys_SetPath(model_path); - free(model_path); - model_path = NULL; - - //create path string to pcipywrap library - char* app_dir = getenv("APP_PATH"); - char* pcipywrap_path; - if(app_dir) - { - pcipywrap_path = malloc(strlen(app_dir) + strlen("/pywrap")); - if (!pcipywrap_path) return PCILIB_ERROR_MEMORY; - sprintf(pcipywrap_path, "%s/%s", "/pywrap", ctx->model); - } - else - { - pcipywrap_path = malloc(strlen("./pywrap")); - if (!pcipywrap_path) return PCILIB_ERROR_MEMORY; - sprintf(pcipywrap_path, "%s", "./pywrap"); - - } - - //set pcipywrap library path to python - PyObject* path = PySys_GetObject("path"); - if(PyList_Append(path, PyString_FromString(pcipywrap_path)) == -1) + pcilib_script_s* module = NULL; + HASH_FIND_STR( scripts, module_name, module); + if(module) { - pcilib_error("Cant set pcipywrap library path to python."); - return PCILIB_ERROR_FAILED; + pcilib_warning("Python module %s is already in hash. Skip init step", module_name); + mode[0] = module->mode; + return 0; } - free(pcipywrap_path); - pcipywrap_path = NULL; - - - //extract module name from script name - char* py_module_name = strtok(module_name, "."); - if(!py_module_name) + //Initialize python module + if(!module_name) { - pcilib_error("Invalid script name specified in XML property (%s)." - " Seems like name doesnt contains extension", module_name); + pcilib_error("Invalid script name specified in XML property (NULL)"); return PCILIB_ERROR_INVALID_DATA; } @@ -336,7 +346,6 @@ int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **mo return PCILIB_ERROR_INVALID_DATA; } - //Initializing pcipywrap module if script use it PyObject* dict = PyModule_GetDict(py_script_module); if(PyDict_Contains(dict, PyString_FromString("pcipywrap"))) @@ -350,16 +359,18 @@ int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **mo //setting pcilib_t instance PyObject_CallMethodObjArgs(pcipywrap_module, - PyUnicode_FromString("setPcilib"), + PyUnicode_FromString("set_pcilib"), PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*)), NULL); } //Success. Create struct and initialize values - module[0] = (pcilib_script_t*)malloc(sizeof(pcilib_script_t)); - module[0]->py_script_module = py_script_module; - module[0]->script_name = module_name; - module[0]->dict = dict; + module = malloc(sizeof(pcilib_script_s)); + module->py_script_module = py_script_module; + module->script_name = malloc(strlen(module_name)); + sprintf(module->script_name, "%s", module_name); + module->dict = dict; + //Setting correct mode mode[0] = 0; @@ -367,32 +378,52 @@ int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **mo mode[0] |= PCILIB_ACCESS_R; if(PyDict_Contains(dict, PyString_FromString("write_to_register"))) mode[0] |= PCILIB_ACCESS_W; + + module->mode = mode[0]; + HASH_ADD_STR( scripts, script_name, module); return 0; } -int pcilib_free_py_script(pcilib_script_t *module) +int pcilib_py_free_script(char* module_name) { - if(module) + pcilib_script_s *module; + HASH_FIND_STR(scripts, module_name, module); + + if(!module) { - if(module->script_name) - { - free(module->script_name); - module->script_name = NULL; - } + //For some reason it will crash if uncomment. printf same warning is ok + //pcilib_warning("Cant find Python module %s in hash. Seems it has already deleted.", module_name); + return 0; + } + + if(module->script_name) + { + free(module->script_name); + module->script_name = NULL; + } - if(module->py_script_module) - { - //PyObject_Free(module->py_script_module); - module->py_script_module = NULL; - } + if(module->py_script_module) + { + //PyObject_Free(module->py_script_module); + module->py_script_module = NULL; } + HASH_DEL(scripts, module); + free(module); return 0; } -int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val) +int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val) { + pcilib_script_s *module; + HASH_FIND_STR(scripts, module_name, module); + + if(!module) + { + pcilib_error("Failed to find script module (%s) in hash", module_name); + return PCILIB_ERROR_NOTFOUND; + } int err; @@ -404,7 +435,7 @@ int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *v return PCILIB_ERROR_FAILED; } - err = pcilib_convert_pyobject_to_val(ctx, ret, val); + err = pcilib_set_value_from_pyobject(ctx, ret, val); if(err) { @@ -414,9 +445,18 @@ int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *v return 0; } -int pcilib_script_write(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val) +int pcilib_script_write(pcilib_t *ctx, char* module_name, pcilib_value_t *val) { - PyObject *input = pcilib_convert_val_to_pyobject(ctx, val); + pcilib_script_s *module; + HASH_FIND_STR(scripts, module_name, module); + + if(!module) + { + pcilib_error("Failed to find script module (%s) in hash", module_name); + return PCILIB_ERROR_NOTFOUND; + } + + PyObject *input = pcilib_get_value_as_pyobject(ctx, val); if(!input) { printf("Failed to convert input value to Python object"); -- cgit v1.2.3 From 1b3342649294c6ce99aeb82664a29eac47687ee5 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Fri, 12 Feb 2016 17:50:57 +0100 Subject: Move python module init code to transfom view constructor Update python logger and python exeption messages Change serialization method in create_pcilib_instance set_pcilib functions --- pcilib/py.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'pcilib/py.c') diff --git a/pcilib/py.c b/pcilib/py.c index 7b1ae79..e448d21 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -244,11 +244,11 @@ void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val) switch(val->type) { case PCILIB_TYPE_INVALID: - pcilib_error("Invalid register output type (PCILIB_TYPE_INVALID)"); + pcilib_warning("Invalid register output type (PCILIB_TYPE_INVALID)"); return NULL; case PCILIB_TYPE_STRING: - pcilib_error("Invalid register output type (PCILIB_TYPE_STRING)"); + pcilib_warning("Invalid register output type (PCILIB_TYPE_STRING)"); return NULL; case PCILIB_TYPE_LONG: @@ -258,7 +258,7 @@ void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val) if(err) { - pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); + pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); return NULL; } return (PyObject*)PyInt_FromLong((long) ret); @@ -271,14 +271,14 @@ void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val) if(err) { - pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); + pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); return NULL; } return (PyObject*)PyFloat_FromDouble((double) ret); } default: - pcilib_error("Invalid register output type (unknown)"); + pcilib_warning("Invalid register output type (unknown)"); return NULL; } } @@ -360,7 +360,7 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t //setting pcilib_t instance PyObject_CallMethodObjArgs(pcipywrap_module, PyUnicode_FromString("set_pcilib"), - PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*)), + PyCObject_FromVoidPtr(ctx, NULL), NULL); } -- cgit v1.2.3 From 398e756263502a98a0c1887dcf38f7ef1fafa84b Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Mon, 15 Feb 2016 13:41:25 +0100 Subject: Fix memory leaks Add GIL states for int pcilib_script_read and pcilib_script_write functions Correct desctructor for create_pcilib_instance return object --- pcilib/py.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'pcilib/py.c') diff --git a/pcilib/py.c b/pcilib/py.c index e448d21..20fa546 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -427,7 +427,9 @@ int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val) int err; + PyGILState_STATE gstate = PyGILState_Ensure(); PyObject *ret = PyObject_CallMethod(module->py_script_module, "read_from_register", "()"); + PyGILState_Release(gstate); if (!ret) { printf("Python script error: "); @@ -436,6 +438,7 @@ int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val) } err = pcilib_set_value_from_pyobject(ctx, ret, val); + Py_XDECREF(ret); if(err) { @@ -463,17 +466,26 @@ int pcilib_script_write(pcilib_t *ctx, char* module_name, pcilib_value_t *val) PyErr_Print(); return PCILIB_ERROR_FAILED; } + PyObject *func_name = PyUnicode_FromString("write_to_register"); - PyObject *ret = PyObject_CallMethodObjArgs(module->py_script_module, - PyUnicode_FromString("write_to_register"), + PyGILState_STATE gstate = PyGILState_Ensure(); + PyObject *ret = PyObject_CallMethodObjArgs(module->py_script_module, + func_name, input, NULL); + PyGILState_Release(gstate); + if (!ret) { printf("Python script error: "); PyErr_Print(); return PCILIB_ERROR_FAILED; } + + //release objects + Py_XDECREF(func_name); + Py_XDECREF(ret); + Py_XDECREF(input); return 0; } -- cgit v1.2.3 From ed9d8f285f4d81e1ce8bb5e7a5b9e471a73c1590 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Tue, 16 Feb 2016 16:30:40 +0100 Subject: 1. Add python thread initialization to pcilib_init_py() -Fix pcilib_script_run_func() work in multithread mode 2. pcilib_close() - Move free_py() code after free views to make view destructors work properly 3. Move script hash to pcilib_py_s 4. Move pcilib_get_logger() pcilib_get_logger_min_prio() and pcilib_get_logger_argument() declarations to error.h 5. Refactor pcilib_get_value_as_pyobject pcilib_set_value_from_pyobject to more unified form 6. Add more memory checks. Fix some string memory allocations. 7. Refactor pcilib_py_s member names. 8. Merge pcilib_script_read() and pcilib_script_write() to pcilib_script_run_func() 9. Update test_pywrap views scripts --- pcilib/py.c | 180 ++++++++++++++++++++++++++++-------------------------------- 1 file changed, 85 insertions(+), 95 deletions(-) (limited to 'pcilib/py.c') diff --git a/pcilib/py.c b/pcilib/py.c index 20fa546..038dba6 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -11,24 +11,20 @@ #include "py.h" #include "error.h" - - -struct pcilib_py_s { - PyObject *main_module; - PyObject *global_dict; - int py_initialized_inside; ///< Flag, shows that Py_Initialize has been called inside class -}; - typedef struct pcilib_script_s { - char* script_name; - PyObject *py_script_module; /**< PyModule object, contains script enviroment */ - PyObject *dict; + char* name; + PyObject *module; /**< PyModule object, contains script enviroment */ pcilib_access_mode_t mode; UT_hash_handle hh; } pcilib_script_s; -struct pcilib_script_s *scripts = NULL; +struct pcilib_py_s { + PyObject *main_module; + PyObject *global_dict; + int py_initialized_inside; ///< Flag, shows that Py_Initialize has been called inside class + struct pcilib_script_s *scripts; +}; int pcilib_init_py(pcilib_t *ctx) { ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t)); @@ -37,6 +33,12 @@ int pcilib_init_py(pcilib_t *ctx) { if(!Py_IsInitialized()) { Py_Initialize(); + + //Since python is being initializing from c programm, it needs + //to initialize threads to works properly with c threads + PyEval_InitThreads(); + PyEval_ReleaseLock(); + ctx->py->py_initialized_inside = 1; } else @@ -70,6 +72,8 @@ int pcilib_init_py(pcilib_t *ctx) { free(model_path); model_dir_added = 1; } + + ctx->py->scripts = NULL; return 0; } @@ -237,53 +241,60 @@ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *va return pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj)); } -void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val) -{ +pcilib_py_object* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val, int *ret) +{ int err; switch(val->type) { case PCILIB_TYPE_INVALID: - pcilib_warning("Invalid register output type (PCILIB_TYPE_INVALID)"); + pcilib_error("Invalid register output type (PCILIB_TYPE_INVALID)"); + if (ret) *ret = PCILIB_ERROR_NOTSUPPORTED; return NULL; case PCILIB_TYPE_STRING: - pcilib_warning("Invalid register output type (PCILIB_TYPE_STRING)"); + pcilib_error("Invalid register output type (PCILIB_TYPE_STRING)"); + if (ret) *ret = PCILIB_ERROR_NOTSUPPORTED; return NULL; case PCILIB_TYPE_LONG: { - long ret; - ret = pcilib_get_value_as_int(ctx, val, &err); + long ret_val; + ret_val = pcilib_get_value_as_int(ctx, val, &err); if(err) { - pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); + if (ret) *ret = err; return NULL; } - return (PyObject*)PyInt_FromLong((long) ret); + + if (ret) *ret = 0; + return (PyObject*)PyInt_FromLong((long) ret_val); } case PCILIB_TYPE_DOUBLE: { - double ret; - ret = pcilib_get_value_as_float(ctx, val, &err); + double ret_val; + ret_val = pcilib_get_value_as_float(ctx, val, &err); if(err) { - pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); + if (ret) *ret = err; return NULL; } - return (PyObject*)PyFloat_FromDouble((double) ret); + + if (ret) *ret = 0; + return (PyObject*)PyFloat_FromDouble((double) ret_val); } default: - pcilib_warning("Invalid register output type (unknown)"); + if (ret) *ret = PCILIB_ERROR_NOTSUPPORTED; + pcilib_error("Invalid register output type (unknown)"); return NULL; } } -int pcilib_set_value_from_pyobject(pcilib_t* ctx, void* pyObjVal, pcilib_value_t *val) +int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py_object* pyObjVal) { PyObject* pyVal = pyObjVal; int err; @@ -321,7 +332,7 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t } pcilib_script_s* module = NULL; - HASH_FIND_STR( scripts, module_name, module); + HASH_FIND_STR( ctx->py->scripts, module_name, module); if(module) { pcilib_warning("Python module %s is already in hash. Skip init step", module_name); @@ -366,10 +377,16 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t //Success. Create struct and initialize values module = malloc(sizeof(pcilib_script_s)); - module->py_script_module = py_script_module; - module->script_name = malloc(strlen(module_name)); - sprintf(module->script_name, "%s", module_name); - module->dict = dict; + if (!module) + return PCILIB_ERROR_MEMORY; + module->module = py_script_module; + module->name = strdup(module_name); + if(!(module->name)) + { + free(module); + return PCILIB_ERROR_MEMORY; + } + sprintf(module->name, "%s", module_name); //Setting correct mode @@ -380,15 +397,15 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t mode[0] |= PCILIB_ACCESS_W; module->mode = mode[0]; - HASH_ADD_STR( scripts, script_name, module); + HASH_ADD_STR( ctx->py->scripts, name, module); return 0; } -int pcilib_py_free_script(char* module_name) +int pcilib_py_free_script(pcilib_t *ctx,char* module_name) { pcilib_script_s *module; - HASH_FIND_STR(scripts, module_name, module); + HASH_FIND_STR(ctx->py->scripts, module_name, module); if(!module) { @@ -397,39 +414,51 @@ int pcilib_py_free_script(char* module_name) return 0; } - if(module->script_name) + if(module->name) { - free(module->script_name); - module->script_name = NULL; + free(module->name); + module->name = NULL; } - if(module->py_script_module) + if(module->module) { - //PyObject_Free(module->py_script_module); - module->py_script_module = NULL; + module->module = NULL; } - HASH_DEL(scripts, module); + HASH_DEL(ctx->py->scripts, module); free(module); return 0; } -int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val) -{ +int pcilib_script_run_func(pcilib_t *ctx, char* module_name, + const char* func_name, pcilib_value_t *val) +{ + int err; pcilib_script_s *module; - HASH_FIND_STR(scripts, module_name, module); - + HASH_FIND_STR(ctx->py->scripts, module_name, module); if(!module) { pcilib_error("Failed to find script module (%s) in hash", module_name); return PCILIB_ERROR_NOTFOUND; } - int err; - PyGILState_STATE gstate = PyGILState_Ensure(); - PyObject *ret = PyObject_CallMethod(module->py_script_module, "read_from_register", "()"); + PyObject *input = pcilib_get_value_as_pyobject(ctx, val, &err); + if(err) + return err; + + PyObject *py_func_name = PyUnicode_FromString(func_name); + PyObject *ret = PyObject_CallMethodObjArgs(module->module, + py_func_name, + input, + NULL); + + + + Py_XDECREF(py_func_name); + Py_XDECREF(input); PyGILState_Release(gstate); + if (!ret) { printf("Python script error: "); @@ -437,55 +466,16 @@ int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val) return PCILIB_ERROR_FAILED; } - err = pcilib_set_value_from_pyobject(ctx, ret, val); - Py_XDECREF(ret); - - if(err) - { - pcilib_error("Failed to convert python script return value to internal type: %i", err); - return err; - } - return 0; -} - -int pcilib_script_write(pcilib_t *ctx, char* module_name, pcilib_value_t *val) -{ - pcilib_script_s *module; - HASH_FIND_STR(scripts, module_name, module); - - if(!module) - { - pcilib_error("Failed to find script module (%s) in hash", module_name); - return PCILIB_ERROR_NOTFOUND; - } - - PyObject *input = pcilib_get_value_as_pyobject(ctx, val); - if(!input) + if(ret != Py_None) { - printf("Failed to convert input value to Python object"); - PyErr_Print(); - return PCILIB_ERROR_FAILED; - } - PyObject *func_name = PyUnicode_FromString("write_to_register"); + err = pcilib_set_value_from_pyobject(ctx, val, ret); + Py_XDECREF(ret); - PyGILState_STATE gstate = PyGILState_Ensure(); - PyObject *ret = PyObject_CallMethodObjArgs(module->py_script_module, - func_name, - input, - NULL); - PyGILState_Release(gstate); - - if (!ret) - { - printf("Python script error: "); - PyErr_Print(); - return PCILIB_ERROR_FAILED; + if(err) + { + pcilib_error("Failed to convert python script return value to internal type: %i", err); + return err; + } } - - //release objects - Py_XDECREF(func_name); - Py_XDECREF(ret); - Py_XDECREF(input); - return 0; } -- cgit v1.2.3 From 3269dce32883e14b45cc490a0cc0037b4c808a68 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Wed, 17 Feb 2016 11:01:22 +0100 Subject: 1. Add cmake BUILD_PYTHON_MODULES option. 2. Rename log options getting functions. 3. py: - pcilib_init_py() - extract pcilib_py_add_script_dir() - pcilib_py_init_script() - extract view-specialized code to pcilib_py_get_transform_script_properties() 3. pcilib_open(): - move pcilib_init_py() to previous position. - add extract pcilib_py_add_script_dir() 4. pcilib_script_s - change hash key. Now it is (const char*) and contains script file name with extension 5. pcipywrap: - Add pcipywrap.h to remove swig generated file complile warnings - remove -includeall swig flag to prevent crash in multi-thread scripts - change set python expetion mechanic --- pcilib/py.c | 124 +++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 80 insertions(+), 44 deletions(-) (limited to 'pcilib/py.c') diff --git a/pcilib/py.c b/pcilib/py.c index 038dba6..8f8040e 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -1,4 +1,6 @@ +#ifdef BUILD_PYTHON_MODULES #include +#endif #include #include @@ -11,11 +13,10 @@ #include "py.h" #include "error.h" +#ifdef BUILD_PYTHON_MODULES typedef struct pcilib_script_s { - char* name; - PyObject *module; /**< PyModule object, contains script enviroment */ - pcilib_access_mode_t mode; - + const char* name; + PyObject *module; /**< PyModule object, contains script enviroment */ UT_hash_handle hh; } pcilib_script_s; @@ -25,8 +26,10 @@ struct pcilib_py_s { int py_initialized_inside; ///< Flag, shows that Py_Initialize has been called inside class struct pcilib_script_s *scripts; }; +#endif int pcilib_init_py(pcilib_t *ctx) { +#ifdef BUILD_PYTHON_MODULES ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t)); if (!ctx->py) return PCILIB_ERROR_MEMORY; @@ -53,6 +56,16 @@ int pcilib_init_py(pcilib_t *ctx) { return PCILIB_ERROR_FAILED; + + + ctx->py->scripts = NULL; +#endif + return 0; +} + +int pcilib_py_add_script_dir(pcilib_t *ctx) +{ +#ifdef BUILD_PYTHON_MODULES //create path string, where the model scripts should be static int model_dir_added = 0; if(!model_dir_added) @@ -72,13 +85,12 @@ int pcilib_init_py(pcilib_t *ctx) { free(model_path); model_dir_added = 1; } - - ctx->py->scripts = NULL; - return 0; +#endif + return 0; } void pcilib_free_py(pcilib_t *ctx) { - +#ifdef BUILD_PYTHON_MODULES int py_initialized_inside = 0; if (ctx->py) { @@ -92,6 +104,7 @@ void pcilib_free_py(pcilib_t *ctx) { if(py_initialized_inside) Py_Finalize(); +#endif } /* @@ -110,7 +123,7 @@ static int pcilib_py_realloc_string(pcilib_t *ctx, size_t required, size_t *size return 0; } */ - +#ifdef BUILD_PYTHON_MODULES static char *pcilib_py_parse_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value) { int i; int err = 0; @@ -216,8 +229,10 @@ static char *pcilib_py_parse_string(pcilib_t *ctx, const char *codestr, pcilib_v return dst; } +#endif int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value) { +#ifdef BUILD_PYTHON_MODULES PyGILState_STATE gstate; char *code; PyObject* obj; @@ -239,10 +254,15 @@ 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)); +#else + pcilib_error("Current build not support python."); + return PCILIB_ERROR_NOTAVAILABLE; +#endif } pcilib_py_object* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val, int *ret) -{ +{ +#ifdef BUILD_PYTHON_MODULES int err; switch(val->type) @@ -292,10 +312,16 @@ pcilib_py_object* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *va pcilib_error("Invalid register output type (unknown)"); return NULL; } +#else + pcilib_error("Current build not support python."); + if (ret) *ret = PCILIB_ERROR_NOTAVAILABLE; + return NULL; +#endif } int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py_object* pyObjVal) { +#ifdef BUILD_PYTHON_MODULES PyObject* pyVal = pyObjVal; int err; @@ -318,12 +344,18 @@ int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py return err; return 0; +#else + pcilib_error("Current build not support python."); + return PCILIB_ERROR_NOTAVAILABLE; +#endif } -int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t *mode) -{ +int pcilib_py_init_script(pcilib_t *ctx, const char* module_name) +{ +#ifdef BUILD_PYTHON_MODULES //extract module name from script name - char* py_module_name = strtok(module_name, "."); + char* py_module_name = strdup(module_name); + py_module_name = strtok(py_module_name, "."); if(!py_module_name) { pcilib_error("Invalid script name specified in XML property (%s)." @@ -336,26 +368,19 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t if(module) { pcilib_warning("Python module %s is already in hash. Skip init step", module_name); - mode[0] = module->mode; return 0; } - //Initialize python module - if(!module_name) - { - pcilib_error("Invalid script name specified in XML property (NULL)"); - return PCILIB_ERROR_INVALID_DATA; - } - //import python script PyObject* py_script_module = PyImport_ImportModule(py_module_name); - if(!py_script_module) { printf("Error in import python module: "); PyErr_Print(); + free(py_module_name); return PCILIB_ERROR_INVALID_DATA; } + free(py_module_name); //Initializing pcipywrap module if script use it PyObject* dict = PyModule_GetDict(py_script_module); @@ -380,45 +405,50 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t if (!module) return PCILIB_ERROR_MEMORY; module->module = py_script_module; - module->name = strdup(module_name); - if(!(module->name)) + module->name = module_name; + HASH_ADD_STR( ctx->py->scripts, name, module); +#endif + return 0; +} + +int pcilib_py_get_transform_script_properties(pcilib_t *ctx, const char* module_name, +pcilib_access_mode_t *mode) +{ +#ifdef BUILD_PYTHON_MODULES + pcilib_script_s *module; + + HASH_FIND_STR(ctx->py->scripts, module_name, module); + if(!module) { - free(module); - return PCILIB_ERROR_MEMORY; + pcilib_error("Failed to find script module (%s) in hash", module_name); + return PCILIB_ERROR_NOTFOUND; } - sprintf(module->name, "%s", module_name); - + PyObject* dict = PyModule_GetDict(module->module); //Setting correct mode mode[0] = 0; if(PyDict_Contains(dict, PyString_FromString("read_from_register"))) mode[0] |= PCILIB_ACCESS_R; if(PyDict_Contains(dict, PyString_FromString("write_to_register"))) - mode[0] |= PCILIB_ACCESS_W; - - module->mode = mode[0]; - HASH_ADD_STR( ctx->py->scripts, name, module); - + mode[0] |= PCILIB_ACCESS_W; return 0; +#else + mode[0] = PCILIB_ACCESS_RW; + return 0; +#endif } -int pcilib_py_free_script(pcilib_t *ctx,char* module_name) +int pcilib_py_free_script(pcilib_t *ctx, const char* module_name) { +#ifdef BUILD_PYTHON_MODULES pcilib_script_s *module; HASH_FIND_STR(ctx->py->scripts, module_name, module); if(!module) { - //For some reason it will crash if uncomment. printf same warning is ok - //pcilib_warning("Cant find Python module %s in hash. Seems it has already deleted.", module_name); + pcilib_warning("Cant find Python module %s in hash. Seems it has already deleted.", module_name); return 0; } - - if(module->name) - { - free(module->name); - module->name = NULL; - } if(module->module) { @@ -427,12 +457,14 @@ int pcilib_py_free_script(pcilib_t *ctx,char* module_name) HASH_DEL(ctx->py->scripts, module); free(module); +#endif return 0; } -int pcilib_script_run_func(pcilib_t *ctx, char* module_name, +int pcilib_script_run_func(pcilib_t *ctx, const char* module_name, const char* func_name, pcilib_value_t *val) -{ +{ +#ifdef BUILD_PYTHON_MODULES int err; pcilib_script_s *module; HASH_FIND_STR(ctx->py->scripts, module_name, module); @@ -478,4 +510,8 @@ int pcilib_script_run_func(pcilib_t *ctx, char* module_name, } } return 0; +#else + pcilib_error("Current build not support python."); + return PCILIB_ERROR_NOTAVAILABLE; +#endif } -- cgit v1.2.3 From 9a9ffd5594a5d27bbecf6160de2c33d44870f5bd Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Wed, 17 Feb 2016 17:20:25 +0100 Subject: Refactor pcipywrap to object --- pcilib/py.c | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) (limited to 'pcilib/py.c') diff --git a/pcilib/py.c b/pcilib/py.c index 8f8040e..372d475 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -23,6 +23,7 @@ typedef struct pcilib_script_s { struct pcilib_py_s { PyObject *main_module; PyObject *global_dict; + PyObject *pcilib_pywrap; int py_initialized_inside; ///< Flag, shows that Py_Initialize has been called inside class struct pcilib_script_s *scripts; }; @@ -54,9 +55,30 @@ int pcilib_init_py(pcilib_t *ctx) { ctx->py->global_dict = PyModule_GetDict(ctx->py->main_module); if (!ctx->py->global_dict) return PCILIB_ERROR_FAILED; + + + + PyObject* py_script_module = PyImport_ImportModule("pcipywrap"); + if(!py_script_module) + { + printf("Error in import python module: "); + PyErr_Print(); + return PCILIB_ERROR_FAILED; + } + PyObject* mod_name = PyString_FromString("Pcipywrap"); + ctx->py->pcilib_pywrap = PyObject_CallMethodObjArgs(py_script_module, + mod_name, + PyCObject_FromVoidPtr(ctx, NULL), + NULL); + Py_XDECREF(mod_name); - + if(!ctx->py->pcilib_pywrap) + { + printf("Error in import python module: "); + PyErr_Print(); + return PCILIB_ERROR_FAILED; + } ctx->py->scripts = NULL; #endif @@ -381,24 +403,6 @@ int pcilib_py_init_script(pcilib_t *ctx, const char* module_name) return PCILIB_ERROR_INVALID_DATA; } free(py_module_name); - - //Initializing pcipywrap module if script use it - PyObject* dict = PyModule_GetDict(py_script_module); - if(PyDict_Contains(dict, PyString_FromString("pcipywrap"))) - { - PyObject* pcipywrap_module = PyDict_GetItemString(dict, "pcipywrap"); - if(!pcipywrap_module) - { - pcilib_error("Cant extract pcipywrap module from script dictionary"); - return PCILIB_ERROR_FAILED; - } - - //setting pcilib_t instance - PyObject_CallMethodObjArgs(pcipywrap_module, - PyUnicode_FromString("set_pcilib"), - PyCObject_FromVoidPtr(ctx, NULL), - NULL); - } //Success. Create struct and initialize values module = malloc(sizeof(pcilib_script_s)); @@ -482,10 +486,9 @@ int pcilib_script_run_func(pcilib_t *ctx, const char* module_name, PyObject *py_func_name = PyUnicode_FromString(func_name); PyObject *ret = PyObject_CallMethodObjArgs(module->module, py_func_name, + ctx->py->pcilib_pywrap, input, NULL); - - Py_XDECREF(py_func_name); Py_XDECREF(input); -- cgit v1.2.3 From 52eb7f4fb76ddf99dedf44332aae7af4df76ab36 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Wed, 17 Feb 2016 18:13:36 +0100 Subject: Add test to repository. Add GIL states to pcilib_set_value_from_pyobject --- pcilib/py.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'pcilib/py.c') diff --git a/pcilib/py.c b/pcilib/py.c index 372d475..a288043 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -347,6 +347,7 @@ int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py PyObject* pyVal = pyObjVal; int err; + PyGILState_STATE gstate = PyGILState_Ensure(); if(PyInt_Check(pyVal)) { err = pcilib_set_value_from_int(ctx, val, PyInt_AsLong(pyVal)); @@ -359,9 +360,11 @@ int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py err = pcilib_set_value_from_static_string(ctx, val, PyString_AsString(pyVal)); else { + PyGILState_Release(gstate); pcilib_error("Invalid input. Input type should be int, float or string."); return PCILIB_ERROR_NOTSUPPORTED; } + PyGILState_Release(gstate); if(err) return err; -- cgit v1.2.3