浏览代码

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.

Vasilii Chernov 8 年之前
父节点
当前提交
5d775d64bd

+ 3 - 1
CMakeLists.txt

@@ -38,7 +38,7 @@ find_package(PkgConfig REQUIRED)
 find_package(Threads REQUIRED)
 
 if (NOT DISABLE_PYTHON)
-    find_package(PythonLibs 2.7 REQUIRED)
+    find_package(PythonLibs 2 REQUIRED)
     find_package(SWIG REQUIRED)
     set(HAVE_PYTHON TRUE)
     include(FindPythonInterp)
@@ -123,6 +123,8 @@ if (NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
    DESTINATION ${CMAKE_BINARY_DIR}
    FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
    )
+   
+   configure_file(${CMAKE_SOURCE_DIR}/pcilib/version.h.in ${CMAKE_SOURCE_DIR}/pcilib/version.h)
 endif(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
 
 install(FILES 

+ 1 - 2
html_server/html_server.py

@@ -137,7 +137,6 @@ def get_registers_list():
    
    value = dict()
    for reg in reg_list:
-      print reg
       try:
          value[reg['name']] = pcilib.read_register(str(reg['name']),
                                                    str(reg['bank']))
@@ -212,4 +211,4 @@ if __name__ == "__main__":
    
    pcilib = pcipywrap.Pcipywrap(device, model)
    pcipywrap.__redirect_logs_to_exeption()
-   app.run(host = HOST_NAME, port = PORT_NUMBER)
+   app.run(host = HOST_NAME, port = PORT_NUMBER, threaded=True)

+ 1 - 1
html_server/templates/base.html

@@ -187,7 +187,7 @@
             }
             
       .infoTable {
-               padding: 5px;
+               padding: 2px;
                
                border: 1px solid #aaa;
                line-height: 28px;

+ 103 - 104
pcilib/locking.c

@@ -102,118 +102,117 @@ pcilib_lock_t *pcilib_get_lock_by_id(pcilib_t *ctx, pcilib_lock_id_t id) {
 }
 
 pcilib_lock_t *pcilib_get_lock(pcilib_t *ctx, pcilib_lock_flags_t flags, const char  *lock_id, ...) {
-    pcilib_lock_id_t i;
-    int err, ret;
-
-    pcilib_lock_t *lock;
-    char buffer[PCILIB_LOCK_SIZE];
-
-	/* we construct the complete lock_id given the parameters of the function*/
-    va_list pa;
-    va_start(pa, lock_id);
-    ret = vsnprintf(buffer, PCILIB_LOCK_SIZE, lock_id, pa);
-    va_end(pa);
-
-    if (ret < 0) {
-	pcilib_error("Failed to construct the lock id, probably arguments does not match the format string (%s)...", lock_id);
-	return NULL;
-    }
-	
-	
-	/* we iterate through locks to see if there is one already with the same name*/	
-	// Would be nice to have hash here
-    for (i = 0; i < PCILIB_MAX_LOCKS; i++) {
-	lock = pcilib_get_lock_by_id(ctx, i);
-
-        const char *name = pcilib_lock_get_name(lock);
-	if (!name) break;
-	
-	if (!strcmp(buffer, name)) {
-	    if ((pcilib_lock_get_flags(lock)&PCILIB_LOCK_FLAG_PERSISTENT) != (flags&PCILIB_LOCK_FLAG_PERSISTENT)) {
-		if (flags&PCILIB_LOCK_FLAG_PERSISTENT)
-		    pcilib_error("Requesting persistent lock (%s), but requested lock is already existing and is robust", name);
-		else
-		    pcilib_error("Requesting robust lock (%s), but requested lock is already existing and is persistent", name);
-		return NULL;
-	    }
-
-#ifndef HAVE_STDATOMIC_H
-	    if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0) {
-		err = pcilib_lock(ctx->locks.locking);
-		if (err) {
-		    pcilib_error("Error (%i) obtaining global lock", err);
-		    return NULL;
-		}
-	    }
-#endif /* ! HAVE_STDATOMIC_H */
-	/* if yes, we increment its ref variable*/
-	    pcilib_lock_ref(lock);
-#ifndef HAVE_STDATOMIC_H
-	    if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
-		pcilib_unlock(ctx->locks.locking);
-#endif /* ! HAVE_STDATOMIC_H */
-
-	    return lock;
-	}
-    }
+   pcilib_lock_id_t i;
+   int err, ret;
 
-    if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0) {
-	err = pcilib_lock(ctx->locks.locking);
-	if (err) {
-	    pcilib_error("Error (%i) obtaining global lock", err);
-	    return NULL;
-	}
-    }
+   pcilib_lock_t *lock;
+   char buffer[PCILIB_LOCK_SIZE];
 
-	// Make sure it was not allocated meanwhile
-    for (; i < PCILIB_MAX_LOCKS; i++) {
-	lock = pcilib_get_lock_by_id(ctx, i);
-
-        const char *name = pcilib_lock_get_name(lock);
-	if (!name) break;
+   /* we construct the complete lock_id given the parameters of the function*/
+   va_list pa;
+   va_start(pa, lock_id);
+   ret = vsnprintf(buffer, PCILIB_LOCK_SIZE, lock_id, pa);
+   va_end(pa);
 
-	if (!strcmp(buffer, name)) {
-	    if ((pcilib_lock_get_flags(lock)&PCILIB_LOCK_FLAG_PERSISTENT) != (flags&PCILIB_LOCK_FLAG_PERSISTENT)) {
-		if (flags&PCILIB_LOCK_FLAG_PERSISTENT)
-		    pcilib_error("Requesting persistent lock (%s), but requested lock is already existing and is robust", name);
-		else
-		    pcilib_error("Requesting robust lock (%s), but requested lock is already existing and is persistent", name);
-		
-		if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
-		    pcilib_unlock(ctx->locks.locking);
-		return NULL;
-	    }
+   if (ret < 0) {
+      pcilib_error("Failed to construct the lock id, probably arguments does not match the format string (%s)...", lock_id);
+      return NULL;
+   }
 
-	    pcilib_lock_ref(lock);
-	    if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
-		pcilib_unlock(ctx->locks.locking);
-	    return lock;
-	}
-    }
 
-    if (i == PCILIB_MAX_LOCKS) {
-	if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
-	    pcilib_unlock(ctx->locks.locking);
-	pcilib_error("Failed to create lock (%s), only %u locks is supported", buffer, PCILIB_MAX_LOCKS);
-	return NULL;
-    }
+   /* we iterate through locks to see if there is one already with the same name*/	
+   // Would be nice to have hash here
+   for (i = 0; i < PCILIB_MAX_LOCKS; i++) {
+      lock = pcilib_get_lock_by_id(ctx, i);
 
-	/* if the lock did not exist before, then we create it*/
-    err = pcilib_init_lock(lock, flags, buffer);
-    
-    if (err) {
-	pcilib_error("Lock initialization failed with error %i", err);
+      const char *name = pcilib_lock_get_name(lock);
+      if (!name) break;
 
-	if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
-	    pcilib_unlock(ctx->locks.locking);
-	
-	return NULL;
-    }
-    
-    if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
-	pcilib_unlock(ctx->locks.locking);
+      if (!strcmp(buffer, name)) {
+         if ((pcilib_lock_get_flags(lock)&PCILIB_LOCK_FLAG_PERSISTENT) != (flags&PCILIB_LOCK_FLAG_PERSISTENT)) {
+            if (flags&PCILIB_LOCK_FLAG_PERSISTENT)
+               pcilib_error("Requesting persistent lock (%s), but requested lock is already existing and is robust", name);
+            else
+               pcilib_error("Requesting robust lock (%s), but requested lock is already existing and is persistent", name);
+            return NULL;
+         }
 
-    return lock;
+#ifndef HAVE_STDATOMIC_H
+         if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0) {
+            err = pcilib_lock(ctx->locks.locking);
+            if (err) {
+               pcilib_error("Error (%i) obtaining global lock", err);
+               return NULL;
+            }
+         }
+#endif /* ! HAVE_STDATOMIC_H */
+         /* if yes, we increment its ref variable*/
+         pcilib_lock_ref(lock);
+         #ifndef HAVE_STDATOMIC_H
+         if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
+            pcilib_unlock(ctx->locks.locking);
+         #endif /* ! HAVE_STDATOMIC_H */
+         return lock;
+      }
+   }
+
+   if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0) {
+      err = pcilib_lock(ctx->locks.locking);
+      if (err) {
+         pcilib_error("Error (%i) obtaining global lock", err);
+         return NULL;
+      }
+   }
+
+   // Make sure it was not allocated meanwhile
+   for (; i < PCILIB_MAX_LOCKS; i++) {
+      lock = pcilib_get_lock_by_id(ctx, i);
+
+      const char *name = pcilib_lock_get_name(lock);
+      if (!name) break;
+
+      if (!strcmp(buffer, name)) {
+         if ((pcilib_lock_get_flags(lock)&PCILIB_LOCK_FLAG_PERSISTENT) != (flags&PCILIB_LOCK_FLAG_PERSISTENT)) {
+            if (flags&PCILIB_LOCK_FLAG_PERSISTENT)
+               pcilib_error("Requesting persistent lock (%s), but requested lock is already existing and is robust", name);
+            else
+               pcilib_error("Requesting robust lock (%s), but requested lock is already existing and is persistent", name);
+
+            if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
+               pcilib_unlock(ctx->locks.locking);
+            return NULL;
+         }
+
+         pcilib_lock_ref(lock);
+         if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
+            pcilib_unlock(ctx->locks.locking);
+         return lock;
+      }
+   }
+
+   if (i == PCILIB_MAX_LOCKS) {
+      if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
+         pcilib_unlock(ctx->locks.locking);
+      pcilib_error("Failed to create lock (%s), only %u locks is supported", buffer, PCILIB_MAX_LOCKS);
+      return NULL;
+   }
+
+   /* if the lock did not exist before, then we create it*/
+   err = pcilib_init_lock(lock, flags, buffer);
+
+   if (err) {
+      pcilib_error("Lock initialization failed with error %i", err);
+
+      if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
+         pcilib_unlock(ctx->locks.locking);
+
+      return NULL;
+   }
+
+   if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
+      pcilib_unlock(ctx->locks.locking);
+
+   return lock;
 }
 
 void pcilib_return_lock(pcilib_t *ctx, pcilib_lock_flags_t flags, pcilib_lock_t *lock) {

+ 2 - 2
pcilib/property.c

@@ -226,8 +226,8 @@ pcilib_property_info_t *pcilib_get_property_list(pcilib_t *ctx, const char *bran
     }
 
     HASH_ITER(hh, dir_hash, dir, dir_tmp) {
-	HASH_DEL(dir_hash, dir);
-	free(dir);
+        HASH_DEL(dir_hash, dir);
+        free(dir);
     }
     HASH_CLEAR(hh, dir_hash);
 

+ 224 - 85
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;
+}

+ 26 - 0
pcilib/py.h

@@ -118,6 +118,32 @@ 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, const char *func, pcilib_value_t *val);
 
+
+/** Clone pcilib_py_t content without scripts hash
+ *  @param[in] in	- pcilib_py_t content to clone
+ *  @param[out] err - error
+ *  @return 		- NULL or cloned pcilib_py_t content pointer on success
+ */
+pcilib_py_t* pcilib_init_py_ctx(pcilib_py_t* in, int *err);
+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);
+int pcilib_py_ctx_add_script_dir(pcilib_py_t *ctx_py, const char *dir);
+void pcilib_free_py_ctx(pcilib_py_t *ctx_py);
+int pcilib_py_ctx_load_script(pcilib_py_t *ctx_py, const char *script_name);
+pcilib_py_object *pcilib_py_ctx_get_scripts_info(pcilib_py_t *ctx_py);
+
+/*!
+ * \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);
+
+/*!
+ * \brief Wrap for PyList_Append, with decrease reference counting after append.
+ */
+void pcilib_pylist_append(pcilib_py_object* list, pcilib_py_object* value);
 #ifdef __cplusplus
 }
 #endif

+ 1 - 1
pywrap/CMakeLists.txt

@@ -25,6 +25,6 @@ install(TARGETS ${SWIG_MODULE_pcipywrap_REAL_NAME} DESTINATION ${PYTHON_SITE_PAC
 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pcipywrap.py DESTINATION ${PYTHON_SITE_PACKAGES})
 
 if (NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
-    file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/server.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+    file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/api_server.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
     file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test_pcipywrap.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
 endif(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)

+ 62 - 85
pywrap/server.py → pywrap/api_server.py

@@ -1,26 +1,20 @@
-import time
 import os
+import sys
+
 import pcipywrap
+
+import time
 import json
-import sys
 from optparse import OptionParser
 
+from multiprocessing import Process, current_process
 from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
-from SocketServer import ThreadingMixIn
-import threading
-
-pcilib = None
-
-class MultiThreadedHTTPServer(ThreadingMixIn, HTTPServer):
-    pass
 
 class PcilibServerHandler(BaseHTTPRequestHandler):
-   locks = list()
-   lock_global = 0
    
-   #def __init__(s, pcilib, *args):
-   #   s.pcilib = pcilib
-   #   BaseHTTPRequestHandler.__init__(s, *args)
+   def __init__(s, pcilib, *args):
+      s.pcilib = pcilib
+      BaseHTTPRequestHandler.__init__(s, *args)
    
    def do_HEAD(s):
       s.send_response(200)
@@ -73,7 +67,7 @@ class PcilibServerHandler(BaseHTTPRequestHandler):
 
             registers = dict()
             try:
-               registers = pcilib.get_registers_list(bank)
+               registers = s.pcilib.get_registers_list(bank)
             except Exception as e:
                s.error(str(e), data) 
                return
@@ -101,7 +95,7 @@ class PcilibServerHandler(BaseHTTPRequestHandler):
             
             register = dict()
             try:
-               register = pcilib.get_register_info(reg, bank)
+               register = s.pcilib.get_register_info(reg, bank)
             except Exception as e:
                s.error(str(e), data) 
                return
@@ -119,7 +113,7 @@ class PcilibServerHandler(BaseHTTPRequestHandler):
             
             properties = dict()
             try:
-               properties = pcilib.get_property_list(branch)
+               properties = s.pcilib.get_property_list(branch)
             except Exception as e:
                s.error(str(e), data) 
                return
@@ -147,7 +141,7 @@ class PcilibServerHandler(BaseHTTPRequestHandler):
             
             value = 0
             try:
-               value = pcilib.read_register(reg, bank)
+               value = s.pcilib.read_register(reg, bank)
             except Exception as e:
                s.error(str(e), data) 
                return
@@ -180,7 +174,7 @@ class PcilibServerHandler(BaseHTTPRequestHandler):
 				   bank = str(bank)
             
             try:
-               pcilib.write_register(value, reg, bank)
+               s.pcilib.write_register(value, reg, bank)
             except Exception as e:
                s.error(str(e), data) 
                return
@@ -202,7 +196,7 @@ class PcilibServerHandler(BaseHTTPRequestHandler):
             
             value = 0
             try:
-               value = pcilib.get_property(prop)
+               value = s.pcilib.get_property(prop)
             except Exception as e:
                s.error(str(e), data) 
                return
@@ -232,7 +226,7 @@ class PcilibServerHandler(BaseHTTPRequestHandler):
             value = str(data.get('value', None))
             
             try:
-               pcilib.set_property(value, prop)
+               s.pcilib.set_property(value, prop)
             except Exception as e:
                s.error(str(e), data) 
                return
@@ -252,20 +246,11 @@ class PcilibServerHandler(BaseHTTPRequestHandler):
             #parse command arguments and convert them to string
             lock_id = str(data.get('lock_id'))
             
-            #check if lock already setted
-            #if lock_id in PcilibServerHandler.locks:
-            #   s.error('Lock with id: ' + lock_id + 
-            #           'already setted by this server',
-            #           data)
-            #   return
-            
             try:
-               pcilib.lock(lock_id)
+               s.pcilib.lock(lock_id)
             except Exception as e:
                s.error(str(e), data) 
                return
-               
-            PcilibServerHandler.locks.append(lock_id)
             
             #Success! Create and send reply
             s.wrapMessageAndSend({'status': 'ok'}, data)
@@ -283,7 +268,7 @@ class PcilibServerHandler(BaseHTTPRequestHandler):
             lock_id = str(data.get('lock_id'))
             
             try:
-               pcilib.try_lock(lock_id)
+               s.pcilib.try_lock(lock_id)
             except Exception as e:
                s.error(str(e), data) 
                return
@@ -295,24 +280,21 @@ class PcilibServerHandler(BaseHTTPRequestHandler):
             
          elif(command == 'unlock'):
             #check required arguments
-            #if not 'lock_id' in data:
-            #   s.error('message doesnt contains "lock_id" field, '
-            #           'which is required for "unlock" command', data)
-            #   return
+            if not 'lock_id' in data:
+               s.error('message doesnt contains "lock_id" field, '
+                       'which is required for "unlock" command', data)
+               return
                
             #parse command arguments and convert them to string
-            #lock_id = str(data.get('lock_id'))
-            
-            #try:
-            #   pcilib.unlock(lock_id)
-            #except Exception as e:
-            #   s.error(str(e), data) 
-            #   return
-            #
-            #remove lock from locks list
-            #if lock_id in PcilibServerHandler.locks:
-            #   PcilibServerHandler.locks.remove(lock_id)
-            time.sleep(20)
+            lock_id = str(data.get('lock_id'))
+            
+            try:
+               print 'unlocking ' + lock_id
+               s.pcilib.unlock(lock_id)
+            except Exception as e:
+               s.error(str(e), data) 
+               return
+
             #Success! Create and send reply
             s.wrapMessageAndSend({'status': 'ok'}, data)
             
@@ -320,20 +302,12 @@ class PcilibServerHandler(BaseHTTPRequestHandler):
             
          #elif(command == 'lock_global'):
          #   #check if global_lock already setted by server
-         #   print 'aaa'
-         #   if PcilibServerHandler.lock_global:
-         #
-         #      s.error('global lock already setted by this server', data)
-         #      return
-         #      
          #   try:
-         #      pcilib.lock_global()
+         #      s.pcilib.lock_global()
          #   except Exception as e:
          #      s.error(str(e), data)
          #      return
          #   
-         #   PcilibServerHandler.lock_global = 1
-         #   
          #   #Success! Create and send reply
          #   s.wrapMessageAndSend({'status': 'ok'}, data)
             
@@ -341,13 +315,11 @@ class PcilibServerHandler(BaseHTTPRequestHandler):
          
          #elif(command == 'unlock_global'):
          #   try:
-         #      pcilib.unlock_global()
+         #      s.pcilib.unlock_global()
          #   except Exception as e:
          #      s.error(str(e), data)
          #      return
          #   
-         #   PcilibServerHandler.lock_global = 0
-         #   
          #   #Success! Create and send reply
          #   s.wrapMessageAndSend({'status': 'ok'}, data)
          
@@ -364,11 +336,11 @@ class PcilibServerHandler(BaseHTTPRequestHandler):
       #print str(s.headers['content-type'])
       #print post_data['some']
       
-   #"""open device context """
+   #open device context 
    #def openPcilibInstance(s, device, model):
-   #   pcilib = pcipywrap.create_pcilib_instance(device, model)
+   #   s.pcilib = pcipywrap.create_pcilib_instance(device, model)
          
-   """Send help message"""
+   #Send help message
    def help(s, received_message = None):
       usage = str('Usage:\n'
       '  Server receive commands via http GET with json packet.\n'
@@ -450,7 +422,7 @@ class PcilibServerHandler(BaseHTTPRequestHandler):
       out = {'status': 'ok', 'usage' : usage}
       s.wrapMessageAndSend(out, received_message)
 
-   """Send error message with text description"""     
+   #Send error message with text description    
    def error(s, info, received_message = None):
       out = dict()
       
@@ -465,9 +437,22 @@ class PcilibServerHandler(BaseHTTPRequestHandler):
       s.end_headers()
       if not received_message is None:
          message['received_message'] = received_message
-      message['thread'] = threading.currentThread().getName()
       s.wfile.write(json.dumps(message))
 
+def serve_forever(server):
+   try:
+      server.serve_forever()
+   except KeyboardInterrupt:
+      pass
+        
+def runpool(server, number_of_processes):
+    # create child processes to act as workers
+    for i in range(number_of_processes-1):
+        Process(target=serve_forever, args=(server,)).start()
+
+    # main process also acts as a worker
+    serve_forever(server)
+
 if __name__ == '__main__':
    
    #parce command line options
@@ -481,6 +466,9 @@ if __name__ == '__main__':
    parser.add_option("-m", "--model",  action="store",
                      type="string", dest="model", default=None,
                      help="Memory model (autodetected)")
+   parser.add_option("-n", "--number_processes",  action="store",
+                     type="int", dest="processes", default=4,
+                     help="Number of processes, used by server (4)")
    opts = parser.parse_args()[0]
    
    HOST_NAME = ''
@@ -510,30 +498,19 @@ if __name__ == '__main__':
    
    #pass Pcipywrap to to server handler
    global pcilib
-   pcilib = pcipywrap.Pcipywrap(DEVICE, MODEL)
-   #def handler(*args):
-   #   PcilibServerHandler(lib, *args)
+   lib = pcipywrap.Pcipywrap(DEVICE, MODEL)
+   def handler(*args):
+      PcilibServerHandler(lib, *args)
    
    #start server
-   httpd = MultiThreadedHTTPServer((HOST_NAME, PORT_NUMBER), PcilibServerHandler)
+   httpd = HTTPServer((HOST_NAME, PORT_NUMBER), handler)
+   runpool(httpd, opts.processes)
    
    print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER)
-   try:
-      httpd.serve_forever()
-   except KeyboardInterrupt:
-      #unlocking global lock
-      if PcilibServerHandler.lock_global:
-         lib.unlock_global()
-         PcilibServerHandler.lock_global = False
-         
-      #delete created locks
-      for lock in PcilibServerHandler.locks:
-         lib.unlock(lock)
-      del PcilibServerHandler.locks[:]
-      pass
-      
-      
-      
+   #try:
+   #   httpd.serve_forever()
+   #except KeyboardInterrupt:
+   #   pass
       
    httpd.server_close()
    print time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, PORT_NUMBER)

+ 208 - 125
pywrap/pcipywrap.c

@@ -1,6 +1,9 @@
 #include "pcipywrap.h"
 #include "locking.h"
 
+#include <dirent.h>
+#include <strings.h>
+
 char* full_log = NULL;
 
 /*!
@@ -101,27 +104,6 @@ void __redirect_logs_to_exeption()
                       pcilib_get_logger_context());
 }
 
-/*!
- * \brief Wrap for PyDict_SetItem, with decrease reference counting after set.
- */
-void pcilib_pydict_set_item(PyObject* dict, PyObject* name, PyObject* 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(PyObject* list, PyObject* value)
-{
-    PyList_Append(list, value);
-    Py_XDECREF(value);
-}
-
 void add_pcilib_value_to_dict(pcilib_t* ctx, PyObject* dict, pcilib_value_t* val, const char *name)
 {
     PyObject *py_val = (PyObject*)pcilib_get_value_as_pyobject(ctx, val, NULL);
@@ -215,126 +197,198 @@ PyObject * pcilib_convert_property_info_to_pyobject(pcilib_t* ctx, pcilib_proper
 
 PyObject * pcilib_convert_register_info_to_pyobject(pcilib_t* ctx, pcilib_register_info_t listItem)
 {
-    PyObject* pylistItem = PyDict_New();
-
-    if(listItem.name)
-        pcilib_pydict_set_item(pylistItem,
-                               PyString_FromString("name"),
-                               PyString_FromString(listItem.name));
-
-    if(listItem.description)
-        pcilib_pydict_set_item(pylistItem,
-                               PyString_FromString("description"),
-                               PyString_FromString(listItem.description));
-
-    if(listItem.bank)
-        pcilib_pydict_set_item(pylistItem,
-                               PyString_FromString("bank"),
-                               PyString_FromString(listItem.bank));
-
-
-    //serialize modes
-    PyObject* modes = PyList_New(0);
-
-    if((listItem.mode & PCILIB_REGISTER_R) == PCILIB_REGISTER_R)
-        pcilib_pylist_append(modes, PyString_FromString("R"));
-    if((listItem.mode & PCILIB_REGISTER_W) == PCILIB_REGISTER_W)
-        pcilib_pylist_append(modes, PyString_FromString("W"));
-    if((listItem.mode & PCILIB_REGISTER_RW) == PCILIB_REGISTER_RW)
-        pcilib_pylist_append(modes, PyString_FromString("RW"));
-    if((listItem.mode & PCILIB_REGISTER_W1C) == PCILIB_REGISTER_W1C)
-        pcilib_pylist_append(modes, PyString_FromString("W1C"));
-    if((listItem.mode & PCILIB_REGISTER_RW1C) == PCILIB_REGISTER_RW1C)
-        pcilib_pylist_append(modes, PyString_FromString("RW1C"));
-    if((listItem.mode & PCILIB_REGISTER_W1I) == PCILIB_REGISTER_W1I)
-        pcilib_pylist_append(modes, PyString_FromString("W1I"));
-    if((listItem.mode & PCILIB_REGISTER_RW1I) == PCILIB_REGISTER_RW1I)
-        pcilib_pylist_append(modes, PyString_FromString("RW1I"));
-    if((listItem.mode & PCILIB_REGISTER_INCONSISTENT) == PCILIB_REGISTER_INCONSISTENT)
-        pcilib_pylist_append(modes, PyString_FromString("NO_CHK"));
-
-    pcilib_pydict_set_item(pylistItem,
-                           PyString_FromString("mode"),
-                           modes);
-
-    pcilib_value_t defval = {0};
-    pcilib_set_value_from_register_value(ctx, &defval, listItem.defvalue);
-    add_pcilib_value_to_dict(ctx, pylistItem, &defval, "defvalue");
-
-    if(listItem.range)
-    {
-        pcilib_value_t minval = {0};
-        pcilib_set_value_from_register_value(ctx, &minval, listItem.range->min);
-
-        pcilib_value_t maxval = {0};
-        pcilib_set_value_from_register_value(ctx, &maxval, listItem.range->max);
-
-        PyObject* range = PyDict_New();
-        add_pcilib_value_to_dict(ctx, range, &minval, "min");
-        add_pcilib_value_to_dict(ctx, range, &maxval, "max");
-        pcilib_pydict_set_item(pylistItem,
-                               PyString_FromString("range"),
-                               range);
-    }
-
-    if(listItem.values)
-    {
+   PyObject* pylistItem = PyDict_New();
+
+   if(listItem.name)
+     pcilib_pydict_set_item(pylistItem,
+                            PyString_FromString("name"),
+                            PyString_FromString(listItem.name));
+
+   if(listItem.description)
+     pcilib_pydict_set_item(pylistItem,
+                            PyString_FromString("description"),
+                            PyString_FromString(listItem.description));
+
+   if(listItem.bank)
+     pcilib_pydict_set_item(pylistItem,
+                            PyString_FromString("bank"),
+                            PyString_FromString(listItem.bank));
+
+
+   //serialize modes
+   PyObject* modes = PyList_New(0);
+
+   if((listItem.mode & PCILIB_REGISTER_R) == PCILIB_REGISTER_R)
+     pcilib_pylist_append(modes, PyString_FromString("R"));
+   if((listItem.mode & PCILIB_REGISTER_W) == PCILIB_REGISTER_W)
+     pcilib_pylist_append(modes, PyString_FromString("W"));
+   if((listItem.mode & PCILIB_REGISTER_RW) == PCILIB_REGISTER_RW)
+     pcilib_pylist_append(modes, PyString_FromString("RW"));
+   if((listItem.mode & PCILIB_REGISTER_W1C) == PCILIB_REGISTER_W1C)
+     pcilib_pylist_append(modes, PyString_FromString("W1C"));
+   if((listItem.mode & PCILIB_REGISTER_RW1C) == PCILIB_REGISTER_RW1C)
+     pcilib_pylist_append(modes, PyString_FromString("RW1C"));
+   if((listItem.mode & PCILIB_REGISTER_W1I) == PCILIB_REGISTER_W1I)
+     pcilib_pylist_append(modes, PyString_FromString("W1I"));
+   if((listItem.mode & PCILIB_REGISTER_RW1I) == PCILIB_REGISTER_RW1I)
+     pcilib_pylist_append(modes, PyString_FromString("RW1I"));
+   if((listItem.mode & PCILIB_REGISTER_INCONSISTENT) == PCILIB_REGISTER_INCONSISTENT)
+     pcilib_pylist_append(modes, PyString_FromString("NO_CHK"));
+
+   pcilib_pydict_set_item(pylistItem,
+                        PyString_FromString("mode"),
+                        modes);
+
+   pcilib_value_t defval = {0};
+   pcilib_set_value_from_register_value(ctx, &defval, listItem.defvalue);
+   add_pcilib_value_to_dict(ctx, pylistItem, &defval, "defvalue");
+
+   if(listItem.range)
+   {
+     pcilib_value_t minval = {0};
+     pcilib_set_value_from_register_value(ctx, &minval, listItem.range->min);
+
+     pcilib_value_t maxval = {0};
+     pcilib_set_value_from_register_value(ctx, &maxval, listItem.range->max);
+
+     PyObject* range = PyDict_New();
+     add_pcilib_value_to_dict(ctx, range, &minval, "min");
+     add_pcilib_value_to_dict(ctx, range, &maxval, "max");
+     pcilib_pydict_set_item(pylistItem,
+                            PyString_FromString("range"),
+                            range);
+   }
 
-        PyObject* values = PyList_New(0);
+   if(listItem.values)
+   {
 
-        for (int j = 0; listItem.values[j].name; j++)
-        {
-            PyObject* valuesItem = PyDict_New();
+     PyObject* values = PyList_New(0);
 
-            pcilib_value_t val = {0};
-            pcilib_set_value_from_register_value(ctx, &val, listItem.values[j].value);
+     for (int j = 0; listItem.values[j].name; j++)
+     {
+         PyObject* valuesItem = PyDict_New();
 
-            pcilib_value_t min = {0};
-            pcilib_set_value_from_register_value(ctx, &min, listItem.values[j].min);
+         pcilib_value_t val = {0};
+         pcilib_set_value_from_register_value(ctx, &val, listItem.values[j].value);
 
-            pcilib_value_t max = {0};
-            pcilib_set_value_from_register_value(ctx, &max, listItem.values[j].max);
+         pcilib_value_t min = {0};
+         pcilib_set_value_from_register_value(ctx, &min, listItem.values[j].min);
 
-            add_pcilib_value_to_dict(ctx, valuesItem, &val, "value");
-            add_pcilib_value_to_dict(ctx, valuesItem, &min, "min");
-            add_pcilib_value_to_dict(ctx, valuesItem, &max, "max");
+         pcilib_value_t max = {0};
+         pcilib_set_value_from_register_value(ctx, &max, listItem.values[j].max);
 
-            if(listItem.values[j].name)
-                pcilib_pydict_set_item(valuesItem,
-                                       PyString_FromString("name"),
-                                       PyString_FromString(listItem.values[j].name));
-            if(listItem.values[j].description)
-            {
-                pcilib_pydict_set_item(valuesItem,
-                                       PyString_FromString("description"),
-                                       PyString_FromString(listItem.values[j].description));
+         add_pcilib_value_to_dict(ctx, valuesItem, &val, "value");
+         add_pcilib_value_to_dict(ctx, valuesItem, &min, "min");
+         add_pcilib_value_to_dict(ctx, valuesItem, &max, "max");
 
-            }
-            pcilib_pylist_append(values, valuesItem);
-        }
+         if(listItem.values[j].name)
+             pcilib_pydict_set_item(valuesItem,
+                                    PyString_FromString("name"),
+                                    PyString_FromString(listItem.values[j].name));
+         if(listItem.values[j].description)
+         {
+             pcilib_pydict_set_item(valuesItem,
+                                    PyString_FromString("description"),
+                                    PyString_FromString(listItem.values[j].description));
 
-        pcilib_pydict_set_item(pylistItem,
-                               PyString_FromString("values"),
-                               values);
-    }
+         }
+         pcilib_pylist_append(values, valuesItem);
+     }
 
-    return pylistItem;
+     pcilib_pydict_set_item(pylistItem,
+                            PyString_FromString("values"),
+                            values);
+   }
 
+   return pylistItem;
 }
 
+
 Pcipywrap *new_Pcipywrap(const char* fpga_device, const char* model)
 {
     //opening device
     pcilib_t* ctx = pcilib_open(fpga_device, model);
-    if(!ctx)
-    {
+    if(!ctx) {
         set_python_exception("Failed pcilib_open(%s, %s)", fpga_device, model);
         return NULL;
     }
+    
     Pcipywrap *self;
     self = (Pcipywrap *) malloc(sizeof(Pcipywrap));
+    if(!self) {
+        pcilib_close(ctx);
+        return (Pcipywrap *)PyExc_MemoryError;
+    }  
     self->shared = 0;
     self->ctx = ctx;
+    self->py = NULL;
+    self->names = NULL;
+    self->names_size = 0;
+
+    
+    //processing pcilib scrips
+    const char *scripts_dir = getenv("PCILIB_SCRIPTS_DIR");
+    if(scripts_dir) {
+      int err = 0;
+
+      self->py = pcilib_init_py_ctx(ctx->py, &err);
+      if(err) {
+         delete_Pcipywrap(self);
+         set_python_exception("Failed pcilib_py_s_clone (%i)", err);
+         return NULL;
+      }
+      
+      //add scripts directory to Python path
+      err = pcilib_py_ctx_add_script_dir(self->py, scripts_dir);
+      if(err) {
+         delete_Pcipywrap(self);
+         set_python_exception("Failed pcilib_py_add_dir (%i)", err);
+         return NULL;
+      }
+      
+      //load scripts in PCILIB_SCRIPTS_DIR
+      self->names = malloc(++(self->names_size) * sizeof(char*));
+      self->names[self->names_size - 1] = NULL;
+      
+      DIR *dir;
+      struct dirent *script_path;
+      dir = opendir(scripts_dir);
+      if (dir) {
+         while ((script_path = readdir(dir)) != NULL) {
+
+            char *py = strrchr(script_path->d_name, '.');
+            if ((!py)||(strcasecmp(py, ".py"))) {
+               continue;
+            }
+
+            char *name = malloc(strlen(script_path->d_name));
+            if(!name) {
+               delete_Pcipywrap(self);
+               return (Pcipywrap *)PyExc_MemoryError;
+            }
+            
+            strcpy(name, script_path->d_name);
+
+            err = pcilib_py_ctx_load_script(self->py, name);
+
+            if(err) {
+               delete_Pcipywrap(self);
+               set_python_exception("pcilib_py_ctx_load_script (%i)", err);
+               return NULL;
+            }
+            
+            self->names = realloc(self->names, ++(self->names_size));
+            if(!self->names) {
+               delete_Pcipywrap(self);
+               return (Pcipywrap *)PyExc_MemoryError;
+            }
+            self->names[self->names_size - 1] = NULL;
+            self->names[self->names_size - 2] = name;
+         }
+         closedir(dir);
+      }
+    }
+    
     return self;
 }
 
@@ -350,14 +404,27 @@ Pcipywrap *create_Pcipywrap(PyObject* ctx)
     self = (Pcipywrap *) malloc(sizeof(Pcipywrap));
     self->shared = 1;
     self->ctx = PyCObject_AsVoidPtr(ctx);
+    self->py = NULL;
+    self->names = NULL;
+    self->names_size = 0;
     return self;
 }
 
 void delete_Pcipywrap(Pcipywrap *self) {
-    if(!self->shared)
-        pcilib_close(self->ctx);
-
-    free(self);
+   if(!self->shared)
+     pcilib_close(self->ctx);
+     
+   pcilib_free_py_ctx(self->py);
+
+   if(self->names) {
+      for(int i = 0; self->names[i]; i++)
+         free(self->names[i]);
+      free(self->names);
+      self->names = NULL;
+      self->names_size = 0;
+   }
+    
+   free(self);
 }
 
 PyObject* Pcipywrap_read_register(Pcipywrap *self, const char *regname, const char *bank)
@@ -464,7 +531,7 @@ PyObject* Pcipywrap_get_registers_list(Pcipywrap *self, const char *bank)
       set_python_exception("pcilib_get_register_list return NULL");
       return NULL;
    }
-
+      
    PyObject* pyList = PyList_New(0);
    for(int i = 0; list[i].name; i++)
    {
@@ -554,7 +621,7 @@ void Pcipywrap_unlock_global(Pcipywrap *self)
 PyObject* Pcipywrap_lock(Pcipywrap *self, const char *lock_id)
 {
     pcilib_lock_t* lock = pcilib_get_lock(self->ctx,
-                                          PCILIB_LOCK_FLAGS_DEFAULT,
+                                          PCILIB_LOCK_FLAG_PERSISTENT,
                                           lock_id);
     if(!lock)
     {
@@ -576,7 +643,7 @@ PyObject* Pcipywrap_lock(Pcipywrap *self, const char *lock_id)
 PyObject* Pcipywrap_try_lock(Pcipywrap *self, const char *lock_id)
 {
     pcilib_lock_t* lock = pcilib_get_lock(self->ctx,
-                                          PCILIB_LOCK_FLAGS_DEFAULT,
+                                          PCILIB_LOCK_FLAG_PERSISTENT,
                                           lock_id);
     if(!lock)
     {
@@ -597,7 +664,7 @@ PyObject* Pcipywrap_try_lock(Pcipywrap *self, const char *lock_id)
 PyObject* Pcipywrap_unlock(Pcipywrap *self, const char *lock_id)
 {
     pcilib_lock_t* lock = pcilib_get_lock(self->ctx,
-                                          PCILIB_LOCK_FLAGS_DEFAULT,
+                                          PCILIB_LOCK_FLAG_PERSISTENT,
                                           lock_id);
     if(!lock)
     {
@@ -609,4 +676,20 @@ PyObject* Pcipywrap_unlock(Pcipywrap *self, const char *lock_id)
     return PyInt_FromLong((long)1);
 }
 
+PyObject* Pcipywrap_get_scripts_list(Pcipywrap *self)
+{
+   return pcilib_py_ctx_get_scripts_info(self->py);
+}
 
+PyObject* Pcipywrap_run_script(Pcipywrap *self, const char* script_name, PyObject* value)
+{
+   int err = 0;
+   PyObject* value_out = pcilib_py_ctx_eval_func(self->py, script_name, "run", value, &err);
+   
+   if(err) {
+    set_python_exception("Failed pcilib_py_ctx_eval_func (%i)", err);
+     return NULL;
+   }
+   
+   return value_out;
+}

+ 15 - 0
pywrap/pcipywrap.h

@@ -5,11 +5,23 @@
 #include "error.h"
 #include <Python.h>
 
+#include "config.h"
+#include "py.h"
+
+#include "pci.h"
+#include "pcilib.h"
+
+
 typedef struct {
+    char** names;
+    int names_size;
+   
     void* ctx;
+    struct pcilib_py_s *py;
     int shared;
 } Pcipywrap;
 
+
 /*!
  * \brief Redirect pcilib standart log stream to exeption text.
  * Logger will accumulate errors untill get message, starts with "#E".
@@ -83,4 +95,7 @@ PyObject* Pcipywrap_lock(Pcipywrap *self, const char *lock_id);
 PyObject* Pcipywrap_try_lock(Pcipywrap *self, const char *lock_id);
 PyObject* Pcipywrap_unlock(Pcipywrap *self, const char *lock_id);
 
+PyObject* Pcipywrap_get_scripts_list(Pcipywrap *self);
+PyObject* Pcipywrap_run_script(Pcipywrap *self, const char* script_name, PyObject* value);
+
 #endif /* PCIPYWRAP_H */

+ 3 - 0
pywrap/pcipywrap.i

@@ -29,5 +29,8 @@ typedef struct {
 		PyObject* lock(const char *lock_id);
 		PyObject* try_lock(const char *lock_id);
 		PyObject* unlock(const char *lock_id);
+      
+      PyObject* get_scripts_list();
+      PyObject* run_script(const char* script_name, PyObject* value);
 	}
 } Pcipywrap;

+ 5 - 1
run

@@ -2,4 +2,8 @@
 
 APP_PATH=`dirname $0`
 
-PYTHONPATH="$APP_PATH/pywrap:$PYTHONPATH" PCILIB_MODEL_DIR="$APP_PATH/xml" LD_LIBRARY_PATH="$APP_PATH/pcilib" $*
+PYTHONPATH="$APP_PATH/pywrap:$PYTHONPATH" \
+PCILIB_MODEL_DIR="$APP_PATH/xml" \
+LD_LIBRARY_PATH="$APP_PATH/pcilib" \
+PCILIB_SCRIPTS_DIR="$APP_PATH/xml/scripts" \
+$*

+ 4 - 0
xml/scripts/test_script.py

@@ -0,0 +1,4 @@
+description='this is a test script'
+
+def run(ctx, inpt):
+   return ctx.get_registers_list();

+ 4 - 0
xml/scripts/test_script2.py

@@ -0,0 +1,4 @@
+description='this is a test script'
+
+def run(ctx, inpt):
+   return ctx.get_registers_list();

+ 3 - 3
xml/test/test_prop_mt.py

@@ -4,15 +4,15 @@ lock = threading.Lock()
 
 def read_from_register(ctx, value):
    with lock:
-      ctx.lock('lock5')
+      ctx.lock('lock12')
       
       cur = read_from_register.counter
       read_from_register.counter += 1
-      for i in range (0, 5):
+      for i in range (0, 60):
          time.sleep(0.1)
          print cur
       out = ctx.get_property('/test/prop3') / 2
-      ctx.unlock('lock5')
+      ctx.unlock('lock12')
       
       return out