34
34
struct pcilib_py_s {
35
35
int finalyze; /**< Indicates, that we are initialized from wrapper and should not destroy Python resources in destructor */
36
36
PyObject *main_module; /**< Main interpreter */
37
PyObject *pywrap_module; /**< Pcilib python wrapper */
38
PyObject *threading_module; /**< Threading module */
37
39
PyObject *global_dict; /**< Dictionary of main interpreter */
38
PyObject *pcilib_pywrap; /**< pcilib wrapper module */
40
PyObject *pcilib_pywrap; /**< pcilib wrapper context */
39
41
pcilib_script_t *script_hash; /**< Hash with loaded scripts */
41
43
# if PY_MAJOR_VERSION >= 3
44
int status; /**< Indicates if python was initialized successfuly (0) or error have occured */
45
pthread_t pth; /**< Helper thread for Python initialization */
46
pthread_cond_t cond; /**< Condition informing about initialization success and request for clean-up */
47
pthread_mutex_t lock; /**< Condition lock */
49
// PyInterpreterState *istate;
50
// PyThreadState *tstate;
45
51
# endif /* PY_MAJOR_VERSION > 3 */
47
53
#endif /* HAVE_PYTHON */
128
134
#ifdef HAVE_PYTHON
135
static int pcilib_py_load_default_modules(pcilib_t *ctx) {
136
PyGILState_STATE gstate = PyGILState_Ensure();
138
ctx->py->main_module = PyImport_AddModule("__parser__");
139
if (!ctx->py->main_module) {
140
PyGILState_Release(gstate);
141
pcilib_python_warning("Error importing python parser");
142
return PCILIB_ERROR_FAILED;
145
ctx->py->global_dict = PyModule_GetDict(ctx->py->main_module);
146
if (!ctx->py->global_dict) {
147
PyGILState_Release(gstate);
148
pcilib_python_warning("Error locating global python dictionary");
149
return PCILIB_ERROR_FAILED;
152
ctx->py->pywrap_module = PyImport_ImportModule(PCILIB_PYTHON_WRAPPER);
153
if (!ctx->py->pywrap_module) {
154
PyGILState_Release(gstate);
155
pcilib_python_warning("Error importing pcilib python wrapper");
156
return PCILIB_ERROR_FAILED;
160
* We need to load threading module here, otherwise if any of the scripts
161
* will use threading, on cleanup Python3 will complain:
162
* Exception KeyError: KeyError(140702199305984,) in <module 'threading' from '/usr/lib64/python3.3/threading.py'> ignored
163
* The idea to load threading module is inspired by
164
* http://stackoverflow.com/questions/8774958/keyerror-in-module-threading-after-a-successful-py-test-run
166
ctx->py->threading_module = PyImport_ImportModule("threading");
167
if (!ctx->py->threading_module) {
168
PyGILState_Release(gstate);
169
pcilib_python_warning("Error importing threading python module");
170
return PCILIB_ERROR_FAILED;
173
PyObject *mod_name = PyUnicode_FromString(PCILIB_PYTHON_WRAPPER);
174
PyObject *pyctx = PyCapsule_New(ctx, "pcilib", NULL);
175
ctx->py->pcilib_pywrap = PyObject_CallMethodObjArgs(ctx->py->pywrap_module, mod_name, pyctx, NULL);
177
Py_XDECREF(mod_name);
179
if (!ctx->py->pcilib_pywrap) {
180
PyGILState_Release(gstate);
181
pcilib_python_warning("Error initializing python wrapper");
182
return PCILIB_ERROR_FAILED;
185
PyGILState_Release(gstate);
189
static void pcilib_py_clean_default_modules(pcilib_t *ctx) {
190
PyGILState_STATE gstate;
192
gstate = PyGILState_Ensure();
194
if (ctx->py->pcilib_pywrap) Py_DECREF(ctx->py->pcilib_pywrap);
196
if (ctx->py->threading_module) Py_DECREF(ctx->py->threading_module);
197
if (ctx->py->pywrap_module) Py_DECREF(ctx->py->pywrap_module);
200
// if (ctx->py->main_module) Py_DECREF(ctx->py->main_module);
202
PyGILState_Release(gstate);
129
206
# if PY_MAJOR_VERSION >= 3
131
208
* Python3 specially treats the main thread intializing Python. It crashes if
146
223
* http://stackoverflow.com/questions/15470367/pyeval-initthreads-in-python-3-how-when-to-call-it-the-saga-continues-ad-naus
148
225
static void *pcilib_py_run_init_thread(void *arg) {
149
pcilib_py_t *py = (pcilib_py_t*)(arg);
226
PyThreadState *state;
227
pcilib_t *ctx = (pcilib_t*)arg;
228
pcilib_py_t *py = ctx->py;
152
232
PyEval_InitThreads();
153
PyEval_ReleaseLock();
234
// state = PyThreadState_Get();
235
// py->istate = state->interp;
237
py->status = pcilib_py_load_default_modules(ctx);
239
state = PyEval_SaveThread();
155
241
// Ensure that main thread waiting for our signal
156
242
pthread_mutex_lock(&(py->lock));
158
244
// Inform the parent thread that initialization is finished
159
245
pthread_cond_signal(&(py->cond));
161
247
// Wait untill cleanup is requested
162
248
pthread_cond_wait(&(py->cond), &(py->lock));
163
249
pthread_mutex_unlock(&(py->lock));
251
PyEval_RestoreThread(state);
252
pcilib_py_clean_default_modules(ctx);
169
257
# endif /* PY_MAJOR_VERSION < 3 */
201
293
// Create initalizer thread and wait until it releases the Lock
202
err = pthread_create(&(ctx->py->pth), NULL, pcilib_py_run_init_thread, ctx->py);
294
err = pthread_create(&(ctx->py->pth), NULL, pcilib_py_run_init_thread, (void*)ctx);
204
296
pthread_mutex_unlock(&(ctx->py->lock));
205
297
pthread_cond_destroy(&(ctx->py->cond));
210
302
// Wait until initialized and keep the lock afterwards until free executed
211
303
pthread_cond_wait(&(ctx->py->cond), &(ctx->py->lock));
304
err = ctx->py->status;
306
// ctx->py->tstate = PyThreadState_New(ctx->py->istate);
212
307
# endif /* PY_MAJOR_VERSION < 3 */
213
308
ctx->py->finalyze = 1;
217
PyGILState_STATE gstate = PyGILState_Ensure();
219
ctx->py->main_module = PyImport_AddModule("__parser__");
220
if (!ctx->py->main_module) {
221
PyGILState_Release(gstate);
222
pcilib_python_warning("Error importing python parser");
223
return PCILIB_ERROR_FAILED;
226
ctx->py->global_dict = PyModule_GetDict(ctx->py->main_module);
227
if (!ctx->py->global_dict) {
228
PyGILState_Release(gstate);
229
pcilib_python_warning("Error locating global python dictionary");
230
return PCILIB_ERROR_FAILED;
233
PyObject *pywrap = PyImport_ImportModule(PCILIB_PYTHON_WRAPPER);
235
PyGILState_Release(gstate);
236
pcilib_python_warning("Error importing pcilib python wrapper");
237
return PCILIB_ERROR_FAILED;
240
PyObject *mod_name = PyUnicode_FromString(PCILIB_PYTHON_WRAPPER);
241
PyObject *pyctx = PyCapsule_New(ctx, "pcilib", NULL);
242
ctx->py->pcilib_pywrap = PyObject_CallMethodObjArgs(pywrap, mod_name, pyctx, NULL);
244
Py_XDECREF(mod_name);
246
if (!ctx->py->pcilib_pywrap) {
247
PyGILState_Release(gstate);
248
pcilib_python_warning("Error initializing python wrapper");
249
return PCILIB_ERROR_FAILED;
252
PyGILState_Release(gstate);
310
err = pcilib_py_load_default_modules(ctx);
253
317
#endif /* HAVE_PYTHON */
322
void pcilib_free_py(pcilib_t *ctx) {
325
PyGILState_STATE gstate;
327
gstate = PyGILState_Ensure();
328
if (ctx->py->script_hash) {
329
pcilib_script_t *script, *script_tmp;
331
HASH_ITER(hh, ctx->py->script_hash, script, script_tmp) {
332
Py_DECREF(script->module);
333
HASH_DEL(ctx->py->script_hash, script);
336
ctx->py->script_hash = NULL;
338
PyGILState_Release(gstate);
340
#if PY_MAJOR_VERSION < 3
341
pcilib_py_clean_default_modules(ctx);
342
#endif /* PY_MAJOR_VERSION < 3 */
344
if (ctx->py->finalyze) {
345
#if PY_MAJOR_VERSION < 3
347
#else /* PY_MAJOR_VERSION < 3 */
348
// PyThreadState_Delete(ctx->py->tstate);
350
// singal python init thread to stop and wait it to finish
351
pthread_cond_signal(&(ctx->py->cond));
352
pthread_mutex_unlock(&(ctx->py->lock));
353
pthread_join(ctx->py->pth, NULL);
355
// destroy synchronization primitives
356
pthread_cond_destroy(&(ctx->py->cond));
357
pthread_mutex_destroy(&(ctx->py->lock));
358
#endif /* PY_MAJOR_VERSION < 3 */
363
#endif /* HAVE_PYTHON */
258
366
int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) {
259
367
#ifdef HAVE_PYTHON
332
void pcilib_free_py(pcilib_t *ctx) {
337
PyGILState_STATE gstate;
339
if (ctx->py->finalyze) finalyze = 1;
341
gstate = PyGILState_Ensure();
343
if (ctx->py->script_hash) {
344
pcilib_script_t *script, *script_tmp;
346
HASH_ITER(hh, ctx->py->script_hash, script, script_tmp) {
347
Py_DECREF(script->module);
348
HASH_DEL(ctx->py->script_hash, script);
351
ctx->py->script_hash = NULL;
354
if (ctx->py->pcilib_pywrap)
355
Py_DECREF(ctx->py->pcilib_pywrap);
357
PyGILState_Release(gstate);
366
#if PY_MAJOR_VERSION < 3
368
#else /* PY_MAJOR_VERSION < 3 */
369
// singal python init thread to stop and wait it to finish
370
pthread_cond_signal(&(ctx->py->cond));
371
pthread_mutex_unlock(&(ctx->py->lock));
372
pthread_join(ctx->py->pth, NULL);
374
// destroy synchronization primitives
375
pthread_cond_destroy(&(ctx->py->cond));
376
pthread_mutex_destroy(&(ctx->py->lock));
377
#endif /* PY_MAJOR_VERSION < 3 */
379
#endif /* HAVE_PYTHON */
382
441
int pcilib_py_load_script(pcilib_t *ctx, const char *script_name) {
383
442
#ifdef HAVE_PYTHON
407
466
pcilib_python_error("Error importing script (%s)", script_name);
408
467
return PCILIB_ERROR_FAILED;
410
PyGILState_Release(gstate);
412
470
module = (pcilib_script_t*)malloc(sizeof(pcilib_script_t));
413
if (!module) return PCILIB_ERROR_MEMORY;
473
PyGILState_Release(gstate);
474
return PCILIB_ERROR_MEMORY;
477
PyGILState_Release(gstate);
415
479
module->module = pymodule;
416
480
module->name = script_name;