summaryrefslogtreecommitdiffstats
path: root/pcilib
diff options
context:
space:
mode:
authorVasilii Chernov <vchernov@inr.ru>2016-02-16 16:30:40 +0100
committerVasilii Chernov <vchernov@inr.ru>2016-02-16 16:30:40 +0100
commited9d8f285f4d81e1ce8bb5e7a5b9e471a73c1590 (patch)
tree8b05ef6a4585b0d585f82c468cf92048a05f79ee /pcilib
parentfc80d8b64672785b4d9c7127e852ca9bf19c9194 (diff)
downloadpcitool-ed9d8f285f4d81e1ce8bb5e7a5b9e471a73c1590.tar.gz
pcitool-ed9d8f285f4d81e1ce8bb5e7a5b9e471a73c1590.tar.bz2
pcitool-ed9d8f285f4d81e1ce8bb5e7a5b9e471a73c1590.tar.xz
pcitool-ed9d8f285f4d81e1ce8bb5e7a5b9e471a73c1590.zip
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
Diffstat (limited to 'pcilib')
-rw-r--r--pcilib/error.h14
-rw-r--r--pcilib/pci.c4
-rw-r--r--pcilib/pcilib.h15
-rw-r--r--pcilib/py.c180
-rw-r--r--pcilib/py.h12
-rw-r--r--pcilib/xml.c2
6 files changed, 108 insertions, 119 deletions
diff --git a/pcilib/error.h b/pcilib/error.h
index a9f4c0b..95774e9 100644
--- a/pcilib/error.h
+++ b/pcilib/error.h
@@ -40,6 +40,20 @@ extern "C" {
void pcilib_log_message(const char *file, int line, pcilib_log_flags_t flags, pcilib_log_priority_t prio, const char *msg, ...);
void pcilib_log_vmessage(const char *file, int line, pcilib_log_flags_t flags, pcilib_log_priority_t prio, const char *msg, va_list va);
+/**
+ * Gets current logger function.
+ */
+pcilib_logger_t pcilib_get_logger();
+
+/**
+ * Gets current logger min priority.
+ */
+pcilib_log_priority_t pcilib_get_logger_min_prio();
+
+/**
+ * Gets current logger argument.
+ */
+void* pcilib_get_logger_argument();
#ifdef __cplusplus
}
diff --git a/pcilib/pci.c b/pcilib/pci.c
index c38097f..58ee4b0 100644
--- a/pcilib/pci.c
+++ b/pcilib/pci.c
@@ -306,8 +306,6 @@ void pcilib_close(pcilib_t *ctx) {
if (ctx->event_plugin)
pcilib_plugin_close(ctx->event_plugin);
-
- pcilib_free_py(ctx);
if (ctx->locks.kmem)
pcilib_free_locking(ctx);
@@ -349,6 +347,8 @@ void pcilib_close(pcilib_t *ctx) {
if (ctx->registers)
free(ctx->registers);
+
+ pcilib_free_py(ctx);
if (ctx->model)
free(ctx->model);
diff --git a/pcilib/pcilib.h b/pcilib/pcilib.h
index 2458320..c32d1fb 100644
--- a/pcilib/pcilib.h
+++ b/pcilib/pcilib.h
@@ -263,21 +263,6 @@ extern "C" {
*/
int pcilib_set_logger(pcilib_log_priority_t min_prio, pcilib_logger_t logger, void *arg);
-/**
- * Gets current logger function.
- */
-pcilib_logger_t pcilib_get_logger();
-
-/**
- * Gets current logger min priority.
- */
-pcilib_log_priority_t pcilib_get_logger_min_prio();
-
-/**
- * Gets current logger argument.
- */
-void* pcilib_get_logger_argument();
-
/** public_api_global
* @}
*/
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;
}
diff --git a/pcilib/py.h b/pcilib/py.h
index 09e2b87..9703706 100644
--- a/pcilib/py.h
+++ b/pcilib/py.h
@@ -4,6 +4,7 @@
#include "pcilib.h"
typedef struct pcilib_py_s pcilib_py_t;
+typedef void pcilib_py_object;
#ifdef __cplusplus
extern "C" {
@@ -15,10 +16,9 @@ void pcilib_free_py(pcilib_t *ctx);
int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t *mode);
-int pcilib_py_free_script(char* module_name);
-int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val);
-int pcilib_script_write(pcilib_t *ctx, char* module_name, pcilib_value_t *val);
-
+int pcilib_py_free_script(pcilib_t *ctx,char* module_name);
+int pcilib_script_run_func(pcilib_t *ctx, char* module_name,
+ const char* func_name, pcilib_value_t *val);
/*!
* \brief Converts pcilib_value_t to PyObject.
@@ -26,7 +26,7 @@ int pcilib_script_write(pcilib_t *ctx, char* module_name, pcilib_value_t *val);
* \param val pointer to pcilib_value_t to convert
* \return PyObject, containing value. NULL with error message, sended to errstream.
*/
-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 *err);
/*!
@@ -36,7 +36,7 @@ void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val);
* \param val initialized polymorphic value
* \return 0 on success or memory error
*/
-int pcilib_set_value_from_pyobject(pcilib_t* ctx, void* pyVal, pcilib_value_t *val);
+int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py_object* pyObjVal);
#ifdef __cplusplus
diff --git a/pcilib/xml.c b/pcilib/xml.c
index 4e95437..adca34e 100644
--- a/pcilib/xml.c
+++ b/pcilib/xml.c
@@ -600,7 +600,7 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp
desc.write_to_reg = value;
if ((value)&&(*value)) mode |= PCILIB_ACCESS_W;
} else if (!strcasecmp(name, "script")) {
- desc.module = malloc(strlen(value));
+ desc.module = strdup(value);
sprintf(desc.module, "%s", value);
break;
}