27
32
UT_hash_handle hh; /**< hash */
35
#if PY_MAJOR_VERSION >= 3
36
typedef struct pcilib_py_s_thread_control {
38
pthread_cond_t cond_finished;
39
pthread_mutex_t cond_finished_lock;
40
} pcilib_py_s_thread_control;
41
#endif /* PY_MAJOR_VERSION < 3 */
30
43
struct pcilib_py_s {
31
44
int finalyze; /**< Indicates, that we are initialized from wrapper and should not destroy Python resources in destructor */
32
45
PyObject *main_module; /**< Main interpreter */
33
46
PyObject *global_dict; /**< Dictionary of main interpreter */
34
47
PyObject *pcilib_pywrap; /**< pcilib wrapper module */
35
48
pcilib_script_t *script_hash; /**< Hash with loaded scripts */
50
#if PY_MAJOR_VERSION >= 3
51
pcilib_py_s_thread_control *thr_ctl; /**< Controller for Python main loop thread for Python 3 */
52
#endif /* PY_MAJOR_VERSION < 3 */
37
54
#endif /* HAVE_PYTHON */
115
132
#endif /* HAVE_PYTHON */
136
#if PY_MAJOR_VERSION >= 3
137
void *pcilib_py_run_side_thread(void *arg) {
138
pcilib_t *ctx = (pcilib_t*)(arg);
139
//Initializing python
141
PyEval_InitThreads();
142
PyEval_ReleaseLock();
144
//send initialization finish signal
145
pthread_cond_signal(&(ctx->py->thr_ctl->cond_finished));
146
pthread_mutex_unlock(&(ctx->py->thr_ctl->cond_finished_lock));
147
pthread_mutex_destroy(&(ctx->py->thr_ctl->cond_finished_lock));
149
//wait untill finish signal
150
pthread_mutex_lock(&(ctx->py->thr_ctl->cond_finished_lock));
151
pthread_cond_wait(&(ctx->py->thr_ctl->cond_finished),
152
&(ctx->py->thr_ctl->cond_finished_lock));
155
#endif /* PY_MAJOR_VERSION < 3 */
156
#endif /* HAVE_PYTHON */
120
158
int pcilib_init_py(pcilib_t *ctx) {
121
159
#ifdef HAVE_PYTHON
122
160
ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t));
123
161
if (!ctx->py) return PCILIB_ERROR_MEMORY;
125
162
memset(ctx->py, 0, sizeof(pcilib_py_t));
127
164
if(!Py_IsInitialized()) {
130
// Since python is being initializing from c programm, it needs to initialize threads to work properly with c threads
131
PyEval_InitThreads();
132
PyEval_ReleaseLock();
133
ctx->py->finalyze = 1;
165
#if PY_MAJOR_VERSION >= 3
166
//create thread controller
167
ctx->py->thr_ctl = malloc(sizeof(pcilib_py_s_thread_control));
168
if(!ctx->py->thr_ctl) return PCILIB_ERROR_MEMORY;
169
memset(ctx->py->thr_ctl, 0, sizeof(pcilib_py_s_thread_control));
171
//create side thread with python main loop
172
pthread_create(&(ctx->py->thr_ctl->pth), NULL, pcilib_py_run_side_thread, ctx);
173
pthread_mutex_lock(&(ctx->py->thr_ctl->cond_finished_lock));
175
//wait until Python initializes
176
pthread_cond_wait(&(ctx->py->thr_ctl->cond_finished),
177
&(ctx->py->thr_ctl->cond_finished_lock));
179
#else /* PY_MAJOR_VERSION < 3 */
181
// Since python is being initializing from c programm, it needs to initialize threads to work properly with c threads
182
PyEval_InitThreads();
183
PyEval_ReleaseLock();
184
#endif /* PY_MAJOR_VERSION < 3 */
185
ctx->py->finalyze = 1;
189
PyGILState_STATE gstate = PyGILState_Ensure();
136
191
ctx->py->main_module = PyImport_AddModule("__parser__");
137
192
if (!ctx->py->main_module) {
138
193
pcilib_python_warning("Error importing python parser");
194
PyGILState_Release(gstate);
139
195
return PCILIB_ERROR_FAILED;
142
198
ctx->py->global_dict = PyModule_GetDict(ctx->py->main_module);
143
199
if (!ctx->py->global_dict) {
144
200
pcilib_python_warning("Error locating global python dictionary");
201
PyGILState_Release(gstate);
145
202
return PCILIB_ERROR_FAILED;
148
205
PyObject *pywrap = PyImport_ImportModule(PCILIB_PYTHON_WRAPPER);
150
207
pcilib_python_warning("Error importing pcilib python wrapper");
208
PyGILState_Release(gstate);
151
209
return PCILIB_ERROR_FAILED;
187
248
if (!script_dir) return PCILIB_ERROR_MEMORY;
188
249
sprintf(script_dir, "%s/%s", model_dir, dir);
252
PyGILState_STATE gstate = PyGILState_Ensure();
191
254
pypath = PySys_GetObject("path");
193
256
pcilib_python_warning("Can't get python path");
257
PyGILState_Release(gstate);
194
258
return PCILIB_ERROR_FAILED;
197
261
pynewdir = PyUnicode_FromString(script_dir);
199
263
pcilib_python_warning("Can't create python string");
264
PyGILState_Release(gstate);
200
265
return PCILIB_ERROR_MEMORY;
203
// Checking if the directory already in the path?
268
// Checking if the directory already in the path?
204
269
pydict = PyDict_New();
206
271
pystr = PyUnicode_FromString("cur");
252
325
ctx->py->script_hash = NULL;
255
if (ctx->py->pcilib_pywrap)
328
if (ctx->py->pcilib_pywrap) {
329
gstate = PyGILState_Ensure();
256
330
Py_DECREF(ctx->py->pcilib_pywrap);
331
PyGILState_Release(gstate);
341
#if PY_MAJOR_VERSION >= 3
343
//stop python side thread
344
pthread_cond_signal(&(thr_ctl->cond_finished));
345
pthread_mutex_unlock(&(thr_ctl->cond_finished_lock));
346
pthread_join(thr_ctl->pth, NULL);
349
//must be finalized in main thread to correctly stop python threading
353
//destroy thread controllers
354
pthread_mutex_destroy(&(thr_ctl->cond_finished_lock));
355
pthread_cond_destroy(&(thr_ctl->cond_finished));
358
#else /* PY_MAJOR_VERSION < 3 */
362
#endif /* PY_MAJOR_VERSION < 3 */
264
366
#endif /* HAVE_PYTHON */
284
387
HASH_FIND_STR(ctx->py->script_hash, script_name, module);
285
388
if (module) return 0;
390
gstate = PyGILState_Ensure();
287
392
pymodule = PyImport_ImportModule(module_name);
289
394
pcilib_python_error("Error importing script (%s)", script_name);
395
PyGILState_Release(gstate);
290
396
return PCILIB_ERROR_FAILED;
399
PyGILState_Release(gstate);
293
401
module = (pcilib_script_t*)malloc(sizeof(pcilib_script_t));
294
402
if (!module) return PCILIB_ERROR_MEMORY;
319
428
pcilib_error("Script (%s) is not loaded yet", script_name);
320
429
return PCILIB_ERROR_NOTFOUND;
432
gstate = PyGILState_Ensure();
323
434
dict = PyModule_GetDict(module->module);
325
436
pcilib_python_error("Error getting dictionary for script (%s)", script_name);
437
PyGILState_Release(gstate);
326
438
return PCILIB_ERROR_FAILED;