/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool

« back to all changes in this revision

Viewing changes to pcilib/py.c

  • Committer: Vasilii Chernov
  • Date: 2016-03-04 08:31:42 UTC
  • mto: This revision was merged to the branch mainline in revision 372.
  • Revision ID: vchernov@inr.ru-20160304083142-5zad1xvhs91ot1j1
Fix python3 initialization from pcilib_t

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
#ifdef HAVE_PYTHON
4
4
# include <Python.h>
 
5
 
 
6
#if PY_MAJOR_VERSION >= 3
 
7
#include <pthread.h>
 
8
#endif /* PY_MAJOR_VERSION >= 3 */
 
9
 
5
10
#endif /* HAVE_PYTHON */
6
11
 
7
12
#include <stdio.h>
27
32
    UT_hash_handle hh;                  /**< hash */
28
33
};
29
34
 
 
35
#if PY_MAJOR_VERSION >= 3
 
36
typedef struct pcilib_py_s_thread_control {
 
37
   pthread_t pth;
 
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 */
 
42
 
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 */
 
49
    
 
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 */
36
53
};
37
54
#endif /* HAVE_PYTHON */
38
55
 
55
72
        PyErr_NormalizeException(&pytype, &pyval, &pytraceback);
56
73
        if (pyval) pystr = PyObject_Str(pyval);
57
74
 
58
 
# if PY_MAJOR_VERSION >= 3
 
75
#if PY_MAJOR_VERSION >= 3
59
76
        if (pytype) {
60
77
            if (PyUnicode_Check(pytype))
61
78
                type = PyUnicode_AsUTF8(pytype);
65
82
        if (pystr) {
66
83
            val = PyUnicode_AsUTF8(pystr);
67
84
        }
68
 
# else /* PY_MAJOR_VERSION >= 3 */
 
85
#else /* PY_MAJOR_VERSION >= 3 */
69
86
        if (pytype) {
70
87
            if (PyString_Check(pytype))
71
88
                type = PyString_AsString(pytype);
75
92
        if (pystr) {
76
93
            val = PyString_AsString(pystr);
77
94
        }
78
 
# endif /*PY_MAJOR_VERSION >= 3*/
 
95
#endif /*PY_MAJOR_VERSION >= 3*/
79
96
    }
80
97
    PyGILState_Release(gstate);
81
98
#endif /* HAVE_PYTHON */
115
132
#endif /* HAVE_PYTHON */
116
133
}
117
134
 
 
135
#ifdef 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
 
140
   Py_Initialize();
 
141
   PyEval_InitThreads();
 
142
   PyEval_ReleaseLock();
 
143
   
 
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));
118
148
 
 
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));
 
153
   return NULL;
 
154
}
 
155
#endif /* PY_MAJOR_VERSION < 3 */
 
156
#endif /* HAVE_PYTHON */
119
157
 
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;
124
 
 
125
162
    memset(ctx->py, 0, sizeof(pcilib_py_t));
126
163
 
127
164
    if(!Py_IsInitialized()) {
128
 
        Py_Initialize();
129
 
        
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));
 
170
      
 
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));
 
174
      
 
175
      //wait until Python initializes
 
176
      pthread_cond_wait(&(ctx->py->thr_ctl->cond_finished),
 
177
                        &(ctx->py->thr_ctl->cond_finished_lock));
 
178
                        
 
179
#else /* PY_MAJOR_VERSION < 3 */
 
180
      Py_Initialize();
 
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;
134
186
    }
135
 
                
 
187
 
 
188
        
 
189
    PyGILState_STATE gstate = PyGILState_Ensure();
 
190
 
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;
140
196
    }
141
197
 
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;
146
203
    }
147
204
 
148
205
    PyObject *pywrap = PyImport_ImportModule(PCILIB_PYTHON_WRAPPER);
149
206
    if (!pywrap) {
150
207
        pcilib_python_warning("Error importing pcilib python wrapper");
 
208
        PyGILState_Release(gstate);
151
209
        return PCILIB_ERROR_FAILED;
152
210
    }
153
211
        
159
217
        
160
218
    if (!ctx->py->pcilib_pywrap) {
161
219
        pcilib_python_warning("Error initializing python wrapper");
 
220
        PyGILState_Release(gstate);
162
221
        return PCILIB_ERROR_FAILED;
163
222
    }
 
223
    
 
224
    PyGILState_Release(gstate);
164
225
#endif /* HAVE_PYTHON */
165
226
 
166
227
    return 0;
187
248
        if (!script_dir) return PCILIB_ERROR_MEMORY;
188
249
        sprintf(script_dir, "%s/%s", model_dir, dir);
189
250
    }
 
251
    
 
252
    PyGILState_STATE gstate = PyGILState_Ensure();
190
253
 
191
254
    pypath = PySys_GetObject("path");
192
255
    if (!pypath) {
193
256
        pcilib_python_warning("Can't get python path");
 
257
        PyGILState_Release(gstate);
194
258
        return PCILIB_ERROR_FAILED;
195
259
    }
196
260
 
197
261
    pynewdir = PyUnicode_FromString(script_dir);
198
262
    if (!pynewdir) {
199
263
        pcilib_python_warning("Can't create python string");
 
264
        PyGILState_Release(gstate);
200
265
        return PCILIB_ERROR_MEMORY;
201
266
    }
202
267
    
203
 
        // Checking if the directory already in the path?
 
268
    // Checking if the directory already in the path?
204
269
    pydict = PyDict_New();
205
270
    if (pydict) {
206
271
        pystr = PyUnicode_FromString("cur");
227
292
 
228
293
    if (err) {
229
294
        pcilib_python_warning("Can't add directory (%s) to python path", script_dir);
 
295
        PyGILState_Release(gstate);
230
296
        return err;
231
297
    }
 
298
    
 
299
    PyGILState_Release(gstate);
232
300
#endif /* HAVE_PYTHON */
233
301
 
234
302
    return 0;
237
305
void pcilib_free_py(pcilib_t *ctx) {
238
306
#ifdef HAVE_PYTHON
239
307
    int finalyze = 0;
240
 
        
 
308
    PyGILState_STATE gstate;
 
309
    
 
310
#if PY_MAJOR_VERSION >= 3
 
311
    pcilib_py_s_thread_control *thr_ctl = ctx->py->thr_ctl;
 
312
#endif /* PY_MAJOR_VERSION < 3 */
 
313
   
241
314
    if (ctx->py) {              
242
315
        if (ctx->py->finalyze) finalyze = 1;
243
316
 
252
325
            ctx->py->script_hash = NULL;
253
326
        }
254
327
 
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);
 
332
         }
 
333
            
257
334
        
258
335
        free(ctx->py);
259
336
        ctx->py = NULL;
260
337
    }
261
338
    
262
 
    if (finalyze)
263
 
        Py_Finalize();
 
339
    
 
340
    if (finalyze) {
 
341
#if PY_MAJOR_VERSION >= 3
 
342
 
 
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);
 
347
       
 
348
       //free python
 
349
       //must be finalized in main thread to correctly stop python threading
 
350
       PyGILState_Ensure();
 
351
       Py_Finalize();
 
352
       
 
353
       //destroy thread controllers
 
354
       pthread_mutex_destroy(&(thr_ctl->cond_finished_lock));
 
355
       pthread_cond_destroy(&(thr_ctl->cond_finished));
 
356
       free(thr_ctl);
 
357
       
 
358
#else /* PY_MAJOR_VERSION < 3 */
 
359
 
 
360
       Py_Finalize();
 
361
       
 
362
#endif /* PY_MAJOR_VERSION < 3 */
 
363
    }
 
364
    
 
365
 
264
366
#endif /* HAVE_PYTHON */
265
367
}
266
368
 
268
370
#ifdef HAVE_PYTHON
269
371
    PyObject* pymodule;
270
372
    pcilib_script_t *module = NULL;
 
373
    PyGILState_STATE gstate;
271
374
 
272
375
    if (!ctx->py) return 0;
273
376
 
284
387
    HASH_FIND_STR(ctx->py->script_hash, script_name, module);
285
388
    if (module) return 0;
286
389
 
 
390
    gstate = PyGILState_Ensure();
 
391
 
287
392
    pymodule = PyImport_ImportModule(module_name);
288
393
    if (!pymodule) {
289
394
        pcilib_python_error("Error importing script (%s)", script_name);
 
395
        PyGILState_Release(gstate);
290
396
        return PCILIB_ERROR_FAILED;
291
397
    }
 
398
    
 
399
    PyGILState_Release(gstate);
292
400
 
293
401
    module = (pcilib_script_t*)malloc(sizeof(pcilib_script_t));
294
402
    if (!module) return PCILIB_ERROR_MEMORY;
307
415
    PyObject *dict;
308
416
    PyObject *pystr;
309
417
    pcilib_script_t *module;
 
418
    PyGILState_STATE gstate;
310
419
 
311
420
    if (!ctx->py) {
312
421
        if (mode_ret) *mode_ret = mode;
319
428
        pcilib_error("Script (%s) is not loaded yet", script_name);
320
429
        return PCILIB_ERROR_NOTFOUND;
321
430
    }
 
431
    
 
432
    gstate = PyGILState_Ensure();
322
433
        
323
434
    dict = PyModule_GetDict(module->module);
324
435
    if (!dict) {
325
436
        pcilib_python_error("Error getting dictionary for script (%s)", script_name);
 
437
        PyGILState_Release(gstate);
326
438
        return PCILIB_ERROR_FAILED;
327
439
    }
328
440
    
337
449
        if (PyDict_Contains(dict, pystr)) mode |= PCILIB_ACCESS_W;
338
450
        Py_DECREF(pystr);
339
451
    }
 
452
    
 
453
    PyGILState_Release(gstate);
340
454
#endif /* HAVE_PYTHON */
341
455
 
342
456
    if (mode_ret) *mode_ret = mode;