Chris@87: Chris@87: /* Thread and interpreter state structures and their interfaces */ Chris@87: Chris@87: Chris@87: #ifndef Py_PYSTATE_H Chris@87: #define Py_PYSTATE_H Chris@87: #ifdef __cplusplus Chris@87: extern "C" { Chris@87: #endif Chris@87: Chris@87: /* State shared between threads */ Chris@87: Chris@87: struct _ts; /* Forward */ Chris@87: struct _is; /* Forward */ Chris@87: Chris@87: typedef struct _is { Chris@87: Chris@87: struct _is *next; Chris@87: struct _ts *tstate_head; Chris@87: Chris@87: PyObject *modules; Chris@87: PyObject *sysdict; Chris@87: PyObject *builtins; Chris@87: PyObject *modules_reloading; Chris@87: Chris@87: PyObject *codec_search_path; Chris@87: PyObject *codec_search_cache; Chris@87: PyObject *codec_error_registry; Chris@87: Chris@87: #ifdef HAVE_DLOPEN Chris@87: int dlopenflags; Chris@87: #endif Chris@87: #ifdef WITH_TSC Chris@87: int tscdump; Chris@87: #endif Chris@87: Chris@87: } PyInterpreterState; Chris@87: Chris@87: Chris@87: /* State unique per thread */ Chris@87: Chris@87: struct _frame; /* Avoid including frameobject.h */ Chris@87: Chris@87: /* Py_tracefunc return -1 when raising an exception, or 0 for success. */ Chris@87: typedef int (*Py_tracefunc)(PyObject *, struct _frame *, int, PyObject *); Chris@87: Chris@87: /* The following values are used for 'what' for tracefunc functions: */ Chris@87: #define PyTrace_CALL 0 Chris@87: #define PyTrace_EXCEPTION 1 Chris@87: #define PyTrace_LINE 2 Chris@87: #define PyTrace_RETURN 3 Chris@87: #define PyTrace_C_CALL 4 Chris@87: #define PyTrace_C_EXCEPTION 5 Chris@87: #define PyTrace_C_RETURN 6 Chris@87: Chris@87: typedef struct _ts { Chris@87: /* See Python/ceval.c for comments explaining most fields */ Chris@87: Chris@87: struct _ts *next; Chris@87: PyInterpreterState *interp; Chris@87: Chris@87: struct _frame *frame; Chris@87: int recursion_depth; Chris@87: /* 'tracing' keeps track of the execution depth when tracing/profiling. Chris@87: This is to prevent the actual trace/profile code from being recorded in Chris@87: the trace/profile. */ Chris@87: int tracing; Chris@87: int use_tracing; Chris@87: Chris@87: Py_tracefunc c_profilefunc; Chris@87: Py_tracefunc c_tracefunc; Chris@87: PyObject *c_profileobj; Chris@87: PyObject *c_traceobj; Chris@87: Chris@87: PyObject *curexc_type; Chris@87: PyObject *curexc_value; Chris@87: PyObject *curexc_traceback; Chris@87: Chris@87: PyObject *exc_type; Chris@87: PyObject *exc_value; Chris@87: PyObject *exc_traceback; Chris@87: Chris@87: PyObject *dict; /* Stores per-thread state */ Chris@87: Chris@87: /* tick_counter is incremented whenever the check_interval ticker Chris@87: * reaches zero. The purpose is to give a useful measure of the number Chris@87: * of interpreted bytecode instructions in a given thread. This Chris@87: * extremely lightweight statistic collector may be of interest to Chris@87: * profilers (like psyco.jit()), although nothing in the core uses it. Chris@87: */ Chris@87: int tick_counter; Chris@87: Chris@87: int gilstate_counter; Chris@87: Chris@87: PyObject *async_exc; /* Asynchronous exception to raise */ Chris@87: long thread_id; /* Thread id where this tstate was created */ Chris@87: Chris@87: int trash_delete_nesting; Chris@87: PyObject *trash_delete_later; Chris@87: Chris@87: /* XXX signal handlers should also be here */ Chris@87: Chris@87: } PyThreadState; Chris@87: Chris@87: Chris@87: PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void); Chris@87: PyAPI_FUNC(void) PyInterpreterState_Clear(PyInterpreterState *); Chris@87: PyAPI_FUNC(void) PyInterpreterState_Delete(PyInterpreterState *); Chris@87: Chris@87: PyAPI_FUNC(PyThreadState *) PyThreadState_New(PyInterpreterState *); Chris@87: PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *); Chris@87: PyAPI_FUNC(void) _PyThreadState_Init(PyThreadState *); Chris@87: PyAPI_FUNC(void) PyThreadState_Clear(PyThreadState *); Chris@87: PyAPI_FUNC(void) PyThreadState_Delete(PyThreadState *); Chris@87: #ifdef WITH_THREAD Chris@87: PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void); Chris@87: #endif Chris@87: Chris@87: PyAPI_FUNC(PyThreadState *) PyThreadState_Get(void); Chris@87: PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *); Chris@87: PyAPI_FUNC(PyObject *) PyThreadState_GetDict(void); Chris@87: PyAPI_FUNC(int) PyThreadState_SetAsyncExc(long, PyObject *); Chris@87: Chris@87: Chris@87: /* Variable and macro for in-line access to current thread state */ Chris@87: Chris@87: PyAPI_DATA(PyThreadState *) _PyThreadState_Current; Chris@87: Chris@87: #ifdef Py_DEBUG Chris@87: #define PyThreadState_GET() PyThreadState_Get() Chris@87: #else Chris@87: #define PyThreadState_GET() (_PyThreadState_Current) Chris@87: #endif Chris@87: Chris@87: typedef Chris@87: enum {PyGILState_LOCKED, PyGILState_UNLOCKED} Chris@87: PyGILState_STATE; Chris@87: Chris@87: /* Ensure that the current thread is ready to call the Python Chris@87: C API, regardless of the current state of Python, or of its Chris@87: thread lock. This may be called as many times as desired Chris@87: by a thread so long as each call is matched with a call to Chris@87: PyGILState_Release(). In general, other thread-state APIs may Chris@87: be used between _Ensure() and _Release() calls, so long as the Chris@87: thread-state is restored to its previous state before the Release(). Chris@87: For example, normal use of the Py_BEGIN_ALLOW_THREADS/ Chris@87: Py_END_ALLOW_THREADS macros are acceptable. Chris@87: Chris@87: The return value is an opaque "handle" to the thread state when Chris@87: PyGILState_Ensure() was called, and must be passed to Chris@87: PyGILState_Release() to ensure Python is left in the same state. Even Chris@87: though recursive calls are allowed, these handles can *not* be shared - Chris@87: each unique call to PyGILState_Ensure must save the handle for its Chris@87: call to PyGILState_Release. Chris@87: Chris@87: When the function returns, the current thread will hold the GIL. Chris@87: Chris@87: Failure is a fatal error. Chris@87: */ Chris@87: PyAPI_FUNC(PyGILState_STATE) PyGILState_Ensure(void); Chris@87: Chris@87: /* Release any resources previously acquired. After this call, Python's Chris@87: state will be the same as it was prior to the corresponding Chris@87: PyGILState_Ensure() call (but generally this state will be unknown to Chris@87: the caller, hence the use of the GILState API.) Chris@87: Chris@87: Every call to PyGILState_Ensure must be matched by a call to Chris@87: PyGILState_Release on the same thread. Chris@87: */ Chris@87: PyAPI_FUNC(void) PyGILState_Release(PyGILState_STATE); Chris@87: Chris@87: /* Helper/diagnostic function - get the current thread state for Chris@87: this thread. May return NULL if no GILState API has been used Chris@87: on the current thread. Note that the main thread always has such a Chris@87: thread-state, even if no auto-thread-state call has been made Chris@87: on the main thread. Chris@87: */ Chris@87: PyAPI_FUNC(PyThreadState *) PyGILState_GetThisThreadState(void); Chris@87: Chris@87: /* The implementation of sys._current_frames() Returns a dict mapping Chris@87: thread id to that thread's current frame. Chris@87: */ Chris@87: PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void); Chris@87: Chris@87: /* Routines for advanced debuggers, requested by David Beazley. Chris@87: Don't use unless you know what you are doing! */ Chris@87: PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void); Chris@87: PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *); Chris@87: PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *); Chris@87: PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *); Chris@87: Chris@87: typedef struct _frame *(*PyThreadFrameGetter)(PyThreadState *self_); Chris@87: Chris@87: /* hook for PyEval_GetFrame(), requested for Psyco */ Chris@87: PyAPI_DATA(PyThreadFrameGetter) _PyThreadState_GetFrame; Chris@87: Chris@87: #ifdef __cplusplus Chris@87: } Chris@87: #endif Chris@87: #endif /* !Py_PYSTATE_H */