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");