-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathInterpreter.h
More file actions
90 lines (78 loc) · 2.25 KB
/
Copy pathInterpreter.h
File metadata and controls
90 lines (78 loc) · 2.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#pragma once
#include <Python.h>
#ifndef PyObject_VAR_HEAD
/// forward declaration, so that you don't need to include "python.h" in other sources
class PyObject;
class PyThreadState;
#endif
#include <vector>
using namespace std;
/** If the application starts we release immediately the global interpreter lock
* (GIL) once the Python interpreter is initialized, i.e. no thread -- including
* the main thread doesn't hold the GIL. Thus, every thread must instantiate an
* object of PyGILStateLocker if it needs to access protected areas in Python or
* areas where the lock is needed. It's best to create the instance on the stack,
* not on the heap.
*/
class PyGILStateLocker
{
public:
PyGILStateLocker()
{
gstate = PyGILState_Ensure();
}
~PyGILStateLocker()
{
PyGILState_Release(gstate);
}
private:
PyGILState_STATE gstate;
};
/**
* If a thread holds the global interpreter lock (GIL) but runs a long operation
* in C where it doesn't need to hold the GIL it can release it temporarily. Or
* if the thread has to run code in the main thread where Python code may be
* executed it must release the GIL to avoid a deadlock. In either case the thread
* must hold the GIL when instantiating an object of PyGILStateRelease.
* As PyGILStateLocker it's best to create an instance of PyGILStateRelease on the
* stack.
*/
class PyGILStateRelease
{
public:
PyGILStateRelease()
{
// release the global interpreter lock
state = PyEval_SaveThread();
}
~PyGILStateRelease()
{
// grab the global interpreter lock again
PyEval_RestoreThread(state);
}
private:
PyThreadState* state;
};
class CInterpreter
{
CInterpreter();
CInterpreter(const CInterpreter&);
CInterpreter& operator=(const CInterpreter&);
public:
static CInterpreter& GetInstance();
virtual ~CInterpreter();
/// must be called from mainthread !!!
const char* startup(int argc , char* argv[]);
void AddPythonPath(const char*);
PyObject* LoadModule(const char*);
bool RedirctStdErrToFile(char* pFileName, char* mode) ;
protected:
friend class PythonCall;
PyThreadState* m_pyThreadState;
PyObject *m_pyMain , *m_pyLoadSummary;
public:
int ReloadPython(void);
private:
void cleanup();
PyThreadState* _global;
};