summaryrefslogtreecommitdiff
path: root/Include/cpython
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2018-11-27 00:20:00 +0100
committerGitHub <noreply@github.com>2018-11-27 00:20:00 +0100
commitf2a9d5c8378cd7eca90b3b197e2cc0989da55014 (patch)
treebdc134a961fcbc0969c0a1115174553db8384ef4 /Include/cpython
parentffedd9ad2a8be4bf82a4d8f2bac3eaee5b44191e (diff)
downloadcpython-git-f2a9d5c8378cd7eca90b3b197e2cc0989da55014.tar.gz
bpo-35134: Create Include/cpython/pystate.h (GH-10733)
Move pystate.h code surrounded by "#ifndef Py_LIMITED_API" to a new Include/cpython/pystate.h header file.
Diffstat (limited to 'Include/cpython')
-rw-r--r--Include/cpython/pystate.h272
1 files changed, 272 insertions, 0 deletions
diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h
new file mode 100644
index 0000000000..78e9a5ed10
--- /dev/null
+++ b/Include/cpython/pystate.h
@@ -0,0 +1,272 @@
+#ifndef Py_CPYTHON_PYSTATE_H
+# error "this header file must not be included directly"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int);
+
+/* Placeholders while working on the new configuration API
+ *
+ * See PEP 432 for final anticipated contents
+ */
+typedef struct {
+ int install_signal_handlers; /* Install signal handlers? -1 means unset */
+ PyObject *argv; /* sys.argv list, can be NULL */
+ PyObject *executable; /* sys.executable str */
+ PyObject *prefix; /* sys.prefix str */
+ PyObject *base_prefix; /* sys.base_prefix str, can be NULL */
+ PyObject *exec_prefix; /* sys.exec_prefix str */
+ PyObject *base_exec_prefix; /* sys.base_exec_prefix str, can be NULL */
+ PyObject *warnoptions; /* sys.warnoptions list, can be NULL */
+ PyObject *xoptions; /* sys._xoptions dict, can be NULL */
+ PyObject *module_search_path; /* sys.path list */
+ PyObject *pycache_prefix; /* sys.pycache_prefix str, can be NULL */
+} _PyMainInterpreterConfig;
+
+#define _PyMainInterpreterConfig_INIT \
+ (_PyMainInterpreterConfig){.install_signal_handlers = -1}
+/* Note: _PyMainInterpreterConfig_INIT sets other fields to 0/NULL */
+
+typedef struct _is {
+
+ struct _is *next;
+ struct _ts *tstate_head;
+
+ int64_t id;
+ int64_t id_refcount;
+ PyThread_type_lock id_mutex;
+
+ PyObject *modules;
+ PyObject *modules_by_index;
+ PyObject *sysdict;
+ PyObject *builtins;
+ PyObject *importlib;
+
+ /* Used in Python/sysmodule.c. */
+ int check_interval;
+
+ /* Used in Modules/_threadmodule.c. */
+ long num_threads;
+ /* Support for runtime thread stack size tuning.
+ A value of 0 means using the platform's default stack size
+ or the size specified by the THREAD_STACK_SIZE macro. */
+ /* Used in Python/thread.c. */
+ size_t pythread_stacksize;
+
+ PyObject *codec_search_path;
+ PyObject *codec_search_cache;
+ PyObject *codec_error_registry;
+ int codecs_initialized;
+ int fscodec_initialized;
+
+ _PyCoreConfig core_config;
+ _PyMainInterpreterConfig config;
+#ifdef HAVE_DLOPEN
+ int dlopenflags;
+#endif
+
+ PyObject *builtins_copy;
+ PyObject *import_func;
+ /* Initialized to PyEval_EvalFrameDefault(). */
+ _PyFrameEvalFunction eval_frame;
+
+ Py_ssize_t co_extra_user_count;
+ freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS];
+
+#ifdef HAVE_FORK
+ PyObject *before_forkers;
+ PyObject *after_forkers_parent;
+ PyObject *after_forkers_child;
+#endif
+ /* AtExit module */
+ void (*pyexitfunc)(PyObject *);
+ PyObject *pyexitmodule;
+
+ uint64_t tstate_next_unique_id;
+} PyInterpreterState;
+
+/* State unique per thread */
+
+/* Py_tracefunc return -1 when raising an exception, or 0 for success. */
+typedef int (*Py_tracefunc)(PyObject *, struct _frame *, int, PyObject *);
+
+/* The following values are used for 'what' for tracefunc functions
+ *
+ * To add a new kind of trace event, also update "trace_init" in
+ * Python/sysmodule.c to define the Python level event name
+ */
+#define PyTrace_CALL 0
+#define PyTrace_EXCEPTION 1
+#define PyTrace_LINE 2
+#define PyTrace_RETURN 3
+#define PyTrace_C_CALL 4
+#define PyTrace_C_EXCEPTION 5
+#define PyTrace_C_RETURN 6
+#define PyTrace_OPCODE 7
+
+
+typedef struct _err_stackitem {
+ /* This struct represents an entry on the exception stack, which is a
+ * per-coroutine state. (Coroutine in the computer science sense,
+ * including the thread and generators).
+ * This ensures that the exception state is not impacted by "yields"
+ * from an except handler.
+ */
+ PyObject *exc_type, *exc_value, *exc_traceback;
+
+ struct _err_stackitem *previous_item;
+
+} _PyErr_StackItem;
+
+
+typedef struct _ts {
+ /* See Python/ceval.c for comments explaining most fields */
+
+ struct _ts *prev;
+ struct _ts *next;
+ PyInterpreterState *interp;
+
+ struct _frame *frame;
+ int recursion_depth;
+ char overflowed; /* The stack has overflowed. Allow 50 more calls
+ to handle the runtime error. */
+ char recursion_critical; /* The current calls must not cause
+ a stack overflow. */
+ int stackcheck_counter;
+
+ /* 'tracing' keeps track of the execution depth when tracing/profiling.
+ This is to prevent the actual trace/profile code from being recorded in
+ the trace/profile. */
+ int tracing;
+ int use_tracing;
+
+ Py_tracefunc c_profilefunc;
+ Py_tracefunc c_tracefunc;
+ PyObject *c_profileobj;
+ PyObject *c_traceobj;
+
+ /* The exception currently being raised */
+ PyObject *curexc_type;
+ PyObject *curexc_value;
+ PyObject *curexc_traceback;
+
+ /* The exception currently being handled, if no coroutines/generators
+ * are present. Always last element on the stack referred to be exc_info.
+ */
+ _PyErr_StackItem exc_state;
+
+ /* Pointer to the top of the stack of the exceptions currently
+ * being handled */
+ _PyErr_StackItem *exc_info;
+
+ PyObject *dict; /* Stores per-thread state */
+
+ int gilstate_counter;
+
+ PyObject *async_exc; /* Asynchronous exception to raise */
+ unsigned long thread_id; /* Thread id where this tstate was created */
+
+ int trash_delete_nesting;
+ PyObject *trash_delete_later;
+
+ /* Called when a thread state is deleted normally, but not when it
+ * is destroyed after fork().
+ * Pain: to prevent rare but fatal shutdown errors (issue 18808),
+ * Thread.join() must wait for the join'ed thread's tstate to be unlinked
+ * from the tstate chain. That happens at the end of a thread's life,
+ * in pystate.c.
+ * The obvious way doesn't quite work: create a lock which the tstate
+ * unlinking code releases, and have Thread.join() wait to acquire that
+ * lock. The problem is that we _are_ at the end of the thread's life:
+ * if the thread holds the last reference to the lock, decref'ing the
+ * lock will delete the lock, and that may trigger arbitrary Python code
+ * if there's a weakref, with a callback, to the lock. But by this time
+ * _PyRuntime.gilstate.tstate_current is already NULL, so only the simplest
+ * of C code can be allowed to run (in particular it must not be possible to
+ * release the GIL).
+ * So instead of holding the lock directly, the tstate holds a weakref to
+ * the lock: that's the value of on_delete_data below. Decref'ing a
+ * weakref is harmless.
+ * on_delete points to _threadmodule.c's static release_sentinel() function.
+ * After the tstate is unlinked, release_sentinel is called with the
+ * weakref-to-lock (on_delete_data) argument, and release_sentinel releases
+ * the indirectly held lock.
+ */
+ void (*on_delete)(void *);
+ void *on_delete_data;
+
+ int coroutine_origin_tracking_depth;
+
+ PyObject *coroutine_wrapper;
+ int in_coroutine_wrapper;
+
+ PyObject *async_gen_firstiter;
+ PyObject *async_gen_finalizer;
+
+ PyObject *context;
+ uint64_t context_ver;
+
+ /* Unique thread state id. */
+ uint64_t id;
+
+ /* XXX signal handlers should also be here */
+
+} PyThreadState;
+
+/* Get the current interpreter state.
+
+ Issue a fatal error if there no current Python thread state or no current
+ interpreter. It cannot return NULL.
+
+ The caller must hold the GIL.*/
+PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_Get(void);
+
+PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*);
+PyAPI_FUNC(void) _PyState_ClearModules(void);
+PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *);
+PyAPI_FUNC(void) _PyThreadState_Init(PyThreadState *);
+PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate);
+PyAPI_FUNC(void) _PyGILState_Reinit(void);
+
+/* Similar to PyThreadState_Get(), but don't issue a fatal error
+ * if it is NULL. */
+PyAPI_FUNC(PyThreadState *) _PyThreadState_UncheckedGet(void);
+
+/* PyGILState */
+
+/* Helper/diagnostic function - return 1 if the current thread
+ currently holds the GIL, 0 otherwise.
+
+ The function returns 1 if _PyGILState_check_enabled is non-zero. */
+PyAPI_FUNC(int) PyGILState_Check(void);
+
+/* Get the single PyInterpreterState used by this process' GILState
+ implementation.
+
+ This function doesn't check for error. Return NULL before _PyGILState_Init()
+ is called and after _PyGILState_Fini() is called.
+
+ See also _PyInterpreterState_Get() and _PyInterpreterState_GET_UNSAFE(). */
+PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void);
+
+/* The implementation of sys._current_frames() Returns a dict mapping
+ thread id to that thread's current frame.
+*/
+PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void);
+
+/* Routines for advanced debuggers, requested by David Beazley.
+ Don't use unless you know what you are doing! */
+PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Main(void);
+PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void);
+PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *);
+PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *);
+PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *);
+
+typedef struct _frame *(*PyThreadFrameGetter)(PyThreadState *self_);
+
+#ifdef __cplusplus
+}
+#endif