1 /**
2   Mirror _pystate.h
3 
4   Thread and interpreter state structures and their interfaces 
5   */
6 module deimos.python.pystate;
7 
8 import deimos.python.pyport;
9 import deimos.python.object;
10 import deimos.python.frameobject;
11 import deimos.python.pyatomic;
12 import deimos.python.moduleobject;
13 
14 extern(C):
15 // Python-header-file: Include/pystate.h:
16 
17 /// _
18 struct PyInterpreterState {
19     /// _
20     PyInterpreterState* next;
21     /// _
22     PyThreadState* tstate_head;
23 
24     /// _
25     PyObject* modules;
26     version(Python_3_0_Or_Later) {
27         /// Availability: 3.*
28         PyObject* modules_by_index;
29     }
30     /// _
31     PyObject* sysdict;
32     /// _
33     PyObject* builtins;
34 
35     /// _
36     PyObject* codec_search_path;
37     /// _
38     PyObject* codec_search_cache;
39     /// _
40     PyObject* codec_error_registry;
41     version(Python_3_0_Or_Later) {
42         /// Availability: 3.*
43         int codecs_initialized;
44         /// Availability: 3.*
45         int fscodec_initialized;
46     }
47 
48     /// _
49     int dlopenflags;
50 
51     // XXX: Not sure what WITH_TSC refers to, or how to conditionalize it in D:
52     //#ifdef WITH_TSC
53     //  int tscdump;
54     //#endif
55 }
56 
57 /// _
58 alias int function(PyObject*, PyFrameObject*, int, PyObject*) Py_tracefunc;
59 
60 /// _
61 enum PyTrace_CALL               = 0;
62 /// ditto
63 enum PyTrace_EXCEPTION          = 1;
64 /// ditto
65 enum PyTrace_LINE 		= 2;
66 /// ditto
67 enum PyTrace_RETURN 	        = 3;
68 /// ditto
69 enum PyTrace_C_CALL             = 4;
70 /// ditto
71 enum PyTrace_C_EXCEPTION        = 5;
72 /// ditto
73 enum PyTrace_C_RETURN           = 6;
74 
75 /// _
76 struct PyThreadState {
77     version(Python_3_4_Or_Later) {
78         /// Availability: >= 3.4
79         PyThreadState* prev;
80     }
81     /// _
82     PyThreadState* next;
83     /// _
84     PyInterpreterState* interp;
85 
86     /// _
87     PyFrameObject* frame;
88     /// _
89     int recursion_depth;
90     version(Python_3_0_Or_Later) {
91         /** The stack has overflowed. Allow 50 more calls
92            to handle the runtime error. */
93         /// Availability: 3.*
94         ubyte overflowed; 
95         /** The current calls must not cause 
96            a stack overflow. */
97         /// Availability: 3.*
98         ubyte recursion_critical; 
99     }
100     /// _
101     int tracing;
102     /// _
103     int use_tracing;
104 
105     /// _
106     Py_tracefunc c_profilefunc;
107     /// _
108     Py_tracefunc c_tracefunc;
109     /// _
110     PyObject* c_profileobj;
111     /// _
112     PyObject* c_traceobj;
113 
114     /// _
115     PyObject* curexc_type;
116     /// _
117     PyObject* curexc_value;
118     /// _
119     PyObject* curexc_traceback;
120 
121     /// _
122     PyObject* exc_type;
123     /// _
124     PyObject* exc_value;
125     /// _
126     PyObject* exc_traceback;
127 
128     /// _
129     PyObject* dict;
130 
131     version(Python_3_4_Or_Later) {
132     }else{
133         /** tick_counter is incremented whenever the check_interval ticker
134          * reaches zero. The purpose is to give a useful measure of the number
135          * of interpreted bytecode instructions in a given thread.  This
136          * extremely lightweight statistic collector may be of interest to
137          * profilers (like psyco.jit()), although nothing in the core uses it.
138          */
139         /// Availability: < 3.4
140         int tick_counter;
141     }
142     /// _
143     int gilstate_counter;
144     /** Asynchronous exception to raise */
145     PyObject* async_exc;
146     /** Thread id where this tstate was created */
147     C_long thread_id;
148 
149     version(Python_3_3_Or_Later) {
150         /// Availability: >= 3.3
151         int trash_delete_nesting;
152 
153         /// Availability: >= 3.3
154         PyObject *trash_delete_later;
155     }
156     version(Python_3_4_Or_Later) {
157         /// Availability: >= 3.4
158         void function(void *) on_delete;
159         /// Availability: >= 3.4
160         void* on_delete_data;
161     }
162 }
163 
164 /// _
165 PyInterpreterState* PyInterpreterState_New();
166 /// _
167 void PyInterpreterState_Clear(PyInterpreterState *);
168 /// _
169 void PyInterpreterState_Delete(PyInterpreterState *);
170 version(Python_3_0_Or_Later) {
171     /// Availability: 3.*
172     int _PyState_AddModule(PyObject*, PyModuleDef*);
173     /// Availability: 3.*
174     PyObject* PyState_FindModule(PyModuleDef*);
175 }
176 
177 /// _
178 PyThreadState* PyThreadState_New(PyInterpreterState *);
179 version(Python_2_6_Or_Later){
180     /// Availability: >= 2.6
181     PyThreadState * _PyThreadState_Prealloc(PyInterpreterState *);
182     /// Availability: >= 2.6
183     void _PyThreadState_Init(PyThreadState *);
184 }
185 /// _
186 void PyThreadState_Clear(PyThreadState *);
187 /// _
188 void PyThreadState_Delete(PyThreadState *);
189 /// _
190 void PyThreadState_DeleteCurrent();
191 version(Python_3_0_Or_Later) {
192     /// Availability: 3.*
193     void _PyGILState_Reinit();
194 }
195 
196 /// _
197 PyThreadState* PyThreadState_Get();
198 /// _
199 PyThreadState* PyThreadState_Swap(PyThreadState*);
200 /// _
201 PyObject_BorrowedRef* PyThreadState_GetDict();
202 /// _
203 int PyThreadState_SetAsyncExc(C_long, PyObject*);
204 
205 version(Python_3_0_Or_Later) {
206     /// _
207     mixin(PyAPI_DATA!"_Py_atomic_address _PyThreadState_Current");
208 
209     /// _
210     auto PyThreadState_GET()() { 
211         return cast(PyThreadState*)
212                 _Py_atomic_load_relaxed(&_PyThreadState_Current);
213     }
214 }else{
215     /// _
216     mixin(PyAPI_DATA!"PyThreadState* _PyThreadState_Current");
217 
218     /// _
219     auto PyThreadState_GET()() { 
220         return _PyThreadState_Current;
221     }
222 }
223 
224 /// _
225 enum PyGILState_STATE {
226     /// _
227     PyGILState_LOCKED, 
228     /// _
229     PyGILState_UNLOCKED
230 };
231 
232 /** Ensure that the current thread is ready to call the Python
233    C API, regardless of the current state of Python, or of its
234    thread lock.  This may be called as many times as desired
235    by a thread so long as each call is matched with a call to
236    PyGILState_Release().  In general, other thread-state APIs may
237    be used between _Ensure() and _Release() calls, so long as the
238    thread-state is restored to its previous state before the Release().
239    For example, normal use of the Py_BEGIN_ALLOW_THREADS/
240    Py_END_ALLOW_THREADS macros are acceptable.
241 
242    The return value is an opaque "handle" to the thread state when
243    PyGILState_Ensure() was called, and must be passed to
244    PyGILState_Release() to ensure Python is left in the same state. Even
245    though recursive calls are allowed, these handles can *not* be shared -
246    each unique call to PyGILState_Ensure must save the handle for its
247    call to PyGILState_Release.
248 
249    When the function returns, the current thread will hold the GIL.
250 
251    Failure is a fatal error.
252 */
253 PyGILState_STATE PyGILState_Ensure();
254 
255 /** Release any resources previously acquired.  After this call, Python's
256    state will be the same as it was prior to the corresponding
257    PyGILState_Ensure() call (but generally this state will be unknown to
258    the caller, hence the use of the GILState API.)
259 
260    Every call to PyGILState_Ensure must be matched by a call to
261    PyGILState_Release on the same thread.
262 */
263 void PyGILState_Release(PyGILState_STATE);
264 
265 /** Helper/diagnostic function - get the current thread state for
266    this thread.  May return NULL if no GILState API has been used
267    on the current thread.  Note that the main thread always has such a
268    thread-state, even if no auto-thread-state call has been made
269    on the main thread.
270 */
271 PyThreadState* PyGILState_GetThisThreadState();
272 /// _
273 PyInterpreterState* PyInterpreterState_Head();
274 /// _
275 PyInterpreterState* PyInterpreterState_Next(PyInterpreterState*);
276 /// _
277 PyThreadState* PyInterpreterState_ThreadHead(PyInterpreterState*);
278 /// _
279 PyThreadState* PyThreadState_Next(PyThreadState*);
280 
281 /// _
282 alias PyFrameObject* function(PyThreadState* self_) PyThreadFrameGetter;
283 
284 /// _
285 mixin(PyAPI_DATA!"PyThreadFrameGetter _PyThreadState_GetFrame");