2017-09-08 02:51:28 -03:00
|
|
|
#ifndef Py_INTERNAL_PYSTATE_H
|
|
|
|
#define Py_INTERNAL_PYSTATE_H
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2019-04-17 18:02:26 -03:00
|
|
|
#ifndef Py_BUILD_CORE
|
|
|
|
# error "this header requires Py_BUILD_CORE define"
|
2018-10-31 21:51:40 -03:00
|
|
|
#endif
|
|
|
|
|
2019-10-02 18:51:20 -03:00
|
|
|
#include "pycore_gil.h" /* struct _gil_runtime_state */
|
|
|
|
#include "pycore_pymem.h" /* struct _gc_runtime_state */
|
|
|
|
#include "pycore_warnings.h" /* struct _warnings_runtime_state */
|
2020-04-13 06:45:21 -03:00
|
|
|
#include "pycore_runtime.h" /* PyRuntimestate */
|
2017-09-08 02:51:28 -03:00
|
|
|
|
|
|
|
|
2019-05-10 18:39:09 -03:00
|
|
|
/* ceval state */
|
|
|
|
|
2019-06-03 13:14:24 -03:00
|
|
|
struct _pending_calls {
|
2019-05-10 18:39:09 -03:00
|
|
|
PyThread_type_lock lock;
|
|
|
|
/* Request for running pending calls. */
|
|
|
|
_Py_atomic_int calls_to_do;
|
|
|
|
/* Request for looking at the `async_exc` field of the current
|
|
|
|
thread state.
|
|
|
|
Guarded by the GIL. */
|
|
|
|
int async_exc;
|
|
|
|
#define NPENDINGCALLS 32
|
|
|
|
struct {
|
|
|
|
int (*func)(void *);
|
|
|
|
void *arg;
|
|
|
|
} calls[NPENDINGCALLS];
|
|
|
|
int first;
|
|
|
|
int last;
|
|
|
|
};
|
|
|
|
|
2020-03-17 14:56:44 -03:00
|
|
|
struct _ceval_state {
|
|
|
|
/* Records whether tracing is on for any thread. Counts the number
|
|
|
|
of threads for which tstate->c_tracefunc is non-NULL, so if the
|
|
|
|
value is 0, we know we don't have to check this thread's
|
|
|
|
c_tracefunc. This speeds up the if statement in
|
|
|
|
_PyEval_EvalFrameDefault() after fast_next_opcode. */
|
|
|
|
int tracing_possible;
|
2020-03-18 22:41:21 -03:00
|
|
|
/* This single variable consolidates all requests to break out of
|
|
|
|
the fast path in the eval loop. */
|
|
|
|
_Py_atomic_int eval_breaker;
|
|
|
|
struct _pending_calls pending;
|
2020-03-17 14:56:44 -03:00
|
|
|
};
|
|
|
|
|
2019-02-23 14:35:52 -04:00
|
|
|
/* interpreter state */
|
2017-09-08 02:51:28 -03:00
|
|
|
|
2019-12-17 08:02:18 -04:00
|
|
|
#define _PY_NSMALLPOSINTS 257
|
|
|
|
#define _PY_NSMALLNEGINTS 5
|
|
|
|
|
2019-02-23 14:35:52 -04:00
|
|
|
// The PyInterpreterState typedef is in Include/pystate.h.
|
|
|
|
struct _is {
|
|
|
|
|
|
|
|
struct _is *next;
|
|
|
|
struct _ts *tstate_head;
|
|
|
|
|
2019-11-19 21:27:56 -04:00
|
|
|
/* Reference to the _PyRuntime global variable. This field exists
|
|
|
|
to not have to pass runtime in addition to tstate to a function.
|
|
|
|
Get runtime from tstate: tstate->interp->runtime. */
|
|
|
|
struct pyruntimestate *runtime;
|
|
|
|
|
2019-02-23 14:35:52 -04:00
|
|
|
int64_t id;
|
|
|
|
int64_t id_refcount;
|
2019-03-15 19:35:46 -03:00
|
|
|
int requires_idref;
|
2019-02-23 14:35:52 -04:00
|
|
|
PyThread_type_lock id_mutex;
|
|
|
|
|
2019-03-09 01:47:07 -04:00
|
|
|
int finalizing;
|
|
|
|
|
2020-03-17 14:56:44 -03:00
|
|
|
struct _ceval_state ceval;
|
2019-11-20 07:25:50 -04:00
|
|
|
struct _gc_runtime_state gc;
|
|
|
|
|
2019-02-23 14:35:52 -04:00
|
|
|
PyObject *modules;
|
|
|
|
PyObject *modules_by_index;
|
|
|
|
PyObject *sysdict;
|
|
|
|
PyObject *builtins;
|
|
|
|
PyObject *importlib;
|
|
|
|
|
|
|
|
/* 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;
|
2019-05-02 15:56:30 -03:00
|
|
|
|
|
|
|
/* fs_codec.encoding is initialized to NULL.
|
|
|
|
Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */
|
|
|
|
struct {
|
|
|
|
char *encoding; /* Filesystem encoding (encoded to UTF-8) */
|
2020-02-05 12:39:57 -04:00
|
|
|
int utf8; /* encoding=="utf-8"? */
|
2019-05-02 15:56:30 -03:00
|
|
|
char *errors; /* Filesystem errors (encoded to UTF-8) */
|
|
|
|
_Py_error_handler error_handler;
|
|
|
|
} fs_codec;
|
2019-02-23 14:35:52 -04:00
|
|
|
|
2019-05-27 11:39:22 -03:00
|
|
|
PyConfig config;
|
2019-02-23 14:35:52 -04:00
|
|
|
#ifdef HAVE_DLOPEN
|
|
|
|
int dlopenflags;
|
|
|
|
#endif
|
2017-09-08 02:51:28 -03:00
|
|
|
|
2019-03-15 20:47:43 -03:00
|
|
|
PyObject *dict; /* Stores per-interpreter state */
|
|
|
|
|
2019-02-23 14:35:52 -04:00
|
|
|
PyObject *builtins_copy;
|
|
|
|
PyObject *import_func;
|
|
|
|
/* Initialized to PyEval_EvalFrameDefault(). */
|
|
|
|
_PyFrameEvalFunction eval_frame;
|
2017-09-08 02:51:28 -03:00
|
|
|
|
2019-02-23 14:35:52 -04:00
|
|
|
Py_ssize_t co_extra_user_count;
|
|
|
|
freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS];
|
2017-09-08 02:51:28 -03:00
|
|
|
|
2019-02-23 14:35:52 -04:00
|
|
|
#ifdef HAVE_FORK
|
|
|
|
PyObject *before_forkers;
|
|
|
|
PyObject *after_forkers_parent;
|
|
|
|
PyObject *after_forkers_child;
|
|
|
|
#endif
|
|
|
|
/* AtExit module */
|
|
|
|
void (*pyexitfunc)(PyObject *);
|
|
|
|
PyObject *pyexitmodule;
|
2017-09-08 02:51:28 -03:00
|
|
|
|
2019-02-23 14:35:52 -04:00
|
|
|
uint64_t tstate_next_unique_id;
|
2019-05-10 14:29:55 -03:00
|
|
|
|
|
|
|
struct _warnings_runtime_state warnings;
|
2019-05-23 12:45:22 -03:00
|
|
|
|
|
|
|
PyObject *audit_hooks;
|
2019-11-20 07:25:50 -04:00
|
|
|
|
2019-11-07 06:08:58 -04:00
|
|
|
struct {
|
|
|
|
struct {
|
|
|
|
int level;
|
|
|
|
int atbol;
|
|
|
|
} listnode;
|
|
|
|
} parser;
|
2019-12-17 08:02:18 -04:00
|
|
|
|
|
|
|
#if _PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS > 0
|
|
|
|
/* Small integers are preallocated in this array so that they
|
|
|
|
can be shared.
|
|
|
|
The integers that are preallocated are those in the range
|
|
|
|
-_PY_NSMALLNEGINTS (inclusive) to _PY_NSMALLPOSINTS (not inclusive).
|
|
|
|
*/
|
|
|
|
PyLongObject* small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS];
|
|
|
|
#endif
|
2019-02-23 14:35:52 -04:00
|
|
|
};
|
2018-01-29 21:23:44 -04:00
|
|
|
|
2019-02-23 14:35:52 -04:00
|
|
|
PyAPI_FUNC(struct _is*) _PyInterpreterState_LookUpID(PY_INT64_T);
|
2018-01-29 21:23:44 -04:00
|
|
|
|
2019-02-23 14:35:52 -04:00
|
|
|
PyAPI_FUNC(int) _PyInterpreterState_IDInitref(struct _is *);
|
|
|
|
PyAPI_FUNC(void) _PyInterpreterState_IDIncref(struct _is *);
|
|
|
|
PyAPI_FUNC(void) _PyInterpreterState_IDDecref(struct _is *);
|
2018-02-16 21:53:40 -04:00
|
|
|
|
2018-01-29 21:23:44 -04:00
|
|
|
|
|
|
|
/* cross-interpreter data registry */
|
|
|
|
|
|
|
|
/* For now we use a global registry of shareable classes. An
|
|
|
|
alternative would be to add a tp_* slot for a class's
|
|
|
|
crossinterpdatafunc. It would be simpler and more efficient. */
|
|
|
|
|
|
|
|
struct _xidregitem;
|
|
|
|
|
|
|
|
struct _xidregitem {
|
|
|
|
PyTypeObject *cls;
|
|
|
|
crossinterpdatafunc getdata;
|
|
|
|
struct _xidregitem *next;
|
|
|
|
};
|
|
|
|
|
2017-09-08 02:51:28 -03:00
|
|
|
|
2020-03-20 09:38:58 -03:00
|
|
|
/* Check if the current thread is the main thread.
|
|
|
|
Use _Py_IsMainInterpreter() to check if it's the main interpreter. */
|
|
|
|
static inline int
|
|
|
|
_Py_IsMainThread(void)
|
|
|
|
{
|
|
|
|
unsigned long thread = PyThread_get_thread_ident();
|
|
|
|
return (thread == _PyRuntime.main_thread);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
_Py_IsMainInterpreter(PyThreadState* tstate)
|
|
|
|
{
|
|
|
|
/* Use directly _PyRuntime rather than tstate->interp->runtime, since
|
|
|
|
this function is used in performance critical code path (ceval) */
|
|
|
|
return (tstate->interp == _PyRuntime.interpreters.main);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Only handle signals on the main thread of the main interpreter. */
|
|
|
|
static inline int
|
2020-04-08 18:35:05 -03:00
|
|
|
_Py_ThreadCanHandleSignals(PyInterpreterState *interp)
|
2020-03-20 09:38:58 -03:00
|
|
|
{
|
2020-04-08 18:35:05 -03:00
|
|
|
return (_Py_IsMainThread() && interp == _PyRuntime.interpreters.main);
|
2020-03-20 09:38:58 -03:00
|
|
|
}
|
2019-11-20 12:34:39 -04:00
|
|
|
|
2017-09-08 02:51:28 -03:00
|
|
|
|
2020-03-20 10:50:35 -03:00
|
|
|
/* Only execute pending calls on the main thread. */
|
|
|
|
static inline int
|
|
|
|
_Py_ThreadCanHandlePendingCalls(void)
|
|
|
|
{
|
|
|
|
return _Py_IsMainThread();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-10-31 21:51:40 -03:00
|
|
|
/* Variable and macro for in-line access to current thread
|
|
|
|
and interpreter state */
|
|
|
|
|
2020-03-06 19:24:23 -04:00
|
|
|
static inline PyThreadState* _PyRuntimeState_GetThreadState(_PyRuntimeState *runtime) {
|
|
|
|
return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->gilstate.tstate_current);
|
|
|
|
}
|
2019-05-10 18:39:09 -03:00
|
|
|
|
2018-10-31 21:51:40 -03:00
|
|
|
/* Get the current Python thread state.
|
|
|
|
|
|
|
|
Efficient macro reading directly the 'gilstate.tstate_current' atomic
|
|
|
|
variable. The macro is unsafe: it does not check for error and it can
|
|
|
|
return NULL.
|
|
|
|
|
|
|
|
The caller must hold the GIL.
|
|
|
|
|
|
|
|
See also PyThreadState_Get() and PyThreadState_GET(). */
|
2020-04-08 18:35:05 -03:00
|
|
|
static inline PyThreadState *_PyThreadState_GET(void) {
|
|
|
|
return _PyRuntimeState_GetThreadState(&_PyRuntime);
|
|
|
|
}
|
2018-10-31 21:51:40 -03:00
|
|
|
|
|
|
|
/* Redefine PyThreadState_GET() as an alias to _PyThreadState_GET() */
|
|
|
|
#undef PyThreadState_GET
|
|
|
|
#define PyThreadState_GET() _PyThreadState_GET()
|
|
|
|
|
|
|
|
/* Get the current interpreter state.
|
|
|
|
|
|
|
|
The macro is unsafe: it does not check for error and it can return NULL.
|
|
|
|
|
|
|
|
The caller must hold the GIL.
|
|
|
|
|
|
|
|
See also _PyInterpreterState_Get()
|
|
|
|
and _PyGILState_GetInterpreterStateUnsafe(). */
|
2020-04-08 18:35:05 -03:00
|
|
|
static inline PyInterpreterState* _PyInterpreterState_GET_UNSAFE(void) {
|
|
|
|
PyThreadState *tstate = _PyThreadState_GET();
|
|
|
|
return tstate->interp;
|
|
|
|
}
|
2018-10-31 21:51:40 -03:00
|
|
|
|
|
|
|
|
2017-09-08 02:51:28 -03:00
|
|
|
/* Other */
|
|
|
|
|
2019-06-03 22:15:09 -03:00
|
|
|
PyAPI_FUNC(void) _PyThreadState_Init(
|
|
|
|
PyThreadState *tstate);
|
|
|
|
PyAPI_FUNC(void) _PyThreadState_DeleteExcept(
|
|
|
|
_PyRuntimeState *runtime,
|
|
|
|
PyThreadState *tstate);
|
2019-05-10 18:39:09 -03:00
|
|
|
|
|
|
|
PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap(
|
|
|
|
struct _gilstate_runtime_state *gilstate,
|
|
|
|
PyThreadState *newts);
|
2019-04-24 11:47:40 -03:00
|
|
|
|
2019-05-27 11:39:22 -03:00
|
|
|
PyAPI_FUNC(PyStatus) _PyInterpreterState_Enable(_PyRuntimeState *runtime);
|
2019-04-24 12:14:33 -03:00
|
|
|
PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime);
|
|
|
|
|
2019-06-19 19:05:23 -03:00
|
|
|
/* Used by _PyImport_Cleanup() */
|
2019-06-18 21:54:39 -03:00
|
|
|
extern void _PyInterpreterState_ClearModules(PyInterpreterState *interp);
|
|
|
|
|
2020-04-12 22:04:28 -03:00
|
|
|
extern PyStatus _PyInterpreterState_SetConfig(
|
|
|
|
PyInterpreterState *interp,
|
|
|
|
const PyConfig *config);
|
|
|
|
|
2019-04-24 12:14:33 -03:00
|
|
|
PyAPI_FUNC(void) _PyGILState_Reinit(_PyRuntimeState *runtime);
|
2017-09-08 02:51:28 -03:00
|
|
|
|
2019-11-22 13:52:27 -04:00
|
|
|
|
|
|
|
PyAPI_FUNC(int) _PyState_AddModule(
|
|
|
|
PyThreadState *tstate,
|
|
|
|
PyObject* module,
|
|
|
|
struct PyModuleDef* def);
|
|
|
|
|
2017-09-08 02:51:28 -03:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif /* !Py_INTERNAL_PYSTATE_H */
|