1#ifndef Py_INTERNAL_RUNTIME_H
2#define Py_INTERNAL_RUNTIME_H
3#ifdef __cplusplus
4extern "C" {
5#endif
6
7#ifndef Py_BUILD_CORE
8#  error "this header requires Py_BUILD_CORE define"
9#endif
10
11#include "pycore_atomic.h"          /* _Py_atomic_address */
12#include "pycore_gil.h"             // struct _gil_runtime_state
13#include "pycore_global_objects.h"  // struct _Py_global_objects
14#include "pycore_interp.h"          // PyInterpreterState
15#include "pycore_unicodeobject.h"   // struct _Py_unicode_runtime_ids
16
17
18/* ceval state */
19
20struct _ceval_runtime_state {
21    /* Request for checking signals. It is shared by all interpreters (see
22       bpo-40513). Any thread of any interpreter can receive a signal, but only
23       the main thread of the main interpreter can handle signals: see
24       _Py_ThreadCanHandleSignals(). */
25    _Py_atomic_int signals_pending;
26    struct _gil_runtime_state gil;
27};
28
29/* GIL state */
30
31struct _gilstate_runtime_state {
32    /* bpo-26558: Flag to disable PyGILState_Check().
33       If set to non-zero, PyGILState_Check() always return 1. */
34    int check_enabled;
35    /* Assuming the current thread holds the GIL, this is the
36       PyThreadState for the current thread. */
37    _Py_atomic_address tstate_current;
38    /* The single PyInterpreterState used by this process'
39       GILState implementation
40    */
41    /* TODO: Given interp_main, it may be possible to kill this ref */
42    PyInterpreterState *autoInterpreterState;
43    Py_tss_t autoTSSkey;
44};
45
46/* Runtime audit hook state */
47
48typedef struct _Py_AuditHookEntry {
49    struct _Py_AuditHookEntry *next;
50    Py_AuditHookFunction hookCFunction;
51    void *userData;
52} _Py_AuditHookEntry;
53
54/* Full Python runtime state */
55
56/* _PyRuntimeState holds the global state for the CPython runtime.
57   That data is exposed in the internal API as a static variable (_PyRuntime).
58   */
59typedef struct pyruntimestate {
60    /* Has been initialized to a safe state.
61
62       In order to be effective, this must be set to 0 during or right
63       after allocation. */
64    int _initialized;
65
66    /* Is running Py_PreInitialize()? */
67    int preinitializing;
68
69    /* Is Python preinitialized? Set to 1 by Py_PreInitialize() */
70    int preinitialized;
71
72    /* Is Python core initialized? Set to 1 by _Py_InitializeCore() */
73    int core_initialized;
74
75    /* Is Python fully initialized? Set to 1 by Py_Initialize() */
76    int initialized;
77
78    /* Set by Py_FinalizeEx(). Only reset to NULL if Py_Initialize()
79       is called again.
80
81       Use _PyRuntimeState_GetFinalizing() and _PyRuntimeState_SetFinalizing()
82       to access it, don't access it directly. */
83    _Py_atomic_address _finalizing;
84
85    struct pyinterpreters {
86        PyThread_type_lock mutex;
87        /* The linked list of interpreters, newest first. */
88        PyInterpreterState *head;
89        /* The runtime's initial interpreter, which has a special role
90           in the operation of the runtime.  It is also often the only
91           interpreter. */
92        PyInterpreterState *main;
93        /* _next_interp_id is an auto-numbered sequence of small
94           integers.  It gets initialized in _PyInterpreterState_Init(),
95           which is called in Py_Initialize(), and used in
96           PyInterpreterState_New().  A negative interpreter ID
97           indicates an error occurred.  The main interpreter will
98           always have an ID of 0.  Overflow results in a RuntimeError.
99           If that becomes a problem later then we can adjust, e.g. by
100           using a Python int. */
101        int64_t next_id;
102    } interpreters;
103    // XXX Remove this field once we have a tp_* slot.
104    struct _xidregistry {
105        PyThread_type_lock mutex;
106        struct _xidregitem *head;
107    } xidregistry;
108
109    unsigned long main_thread;
110
111#define NEXITFUNCS 32
112    void (*exitfuncs[NEXITFUNCS])(void);
113    int nexitfuncs;
114
115    struct _ceval_runtime_state ceval;
116    struct _gilstate_runtime_state gilstate;
117
118    PyPreConfig preconfig;
119
120    // Audit values must be preserved when Py_Initialize()/Py_Finalize()
121    // is called multiple times.
122    Py_OpenCodeHookFunction open_code_hook;
123    void *open_code_userdata;
124    _Py_AuditHookEntry *audit_hook_head;
125
126    struct _Py_unicode_runtime_ids unicode_ids;
127
128    /* All the objects that are shared by the runtime's interpreters. */
129    struct _Py_global_objects global_objects;
130
131    /* The following fields are here to avoid allocation during init.
132       The data is exposed through _PyRuntimeState pointer fields.
133       These fields should not be accessed directly outside of init.
134
135       All other _PyRuntimeState pointer fields are populated when
136       needed and default to NULL.
137
138       For now there are some exceptions to that rule, which require
139       allocation during init.  These will be addressed on a case-by-case
140       basis.  Most notably, we don't pre-allocated the several mutex
141       (PyThread_type_lock) fields, because on Windows we only ever get
142       a pointer type.
143       */
144
145    /* PyInterpreterState.interpreters.main */
146    PyInterpreterState _main_interpreter;
147} _PyRuntimeState;
148
149
150/* other API */
151
152PyAPI_DATA(_PyRuntimeState) _PyRuntime;
153
154PyAPI_FUNC(PyStatus) _PyRuntimeState_Init(_PyRuntimeState *runtime);
155PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime);
156
157#ifdef HAVE_FORK
158extern PyStatus _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime);
159#endif
160
161/* Initialize _PyRuntimeState.
162   Return NULL on success, or return an error message on failure. */
163PyAPI_FUNC(PyStatus) _PyRuntime_Initialize(void);
164
165PyAPI_FUNC(void) _PyRuntime_Finalize(void);
166
167
168static inline PyThreadState*
169_PyRuntimeState_GetFinalizing(_PyRuntimeState *runtime) {
170    return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->_finalizing);
171}
172
173static inline void
174_PyRuntimeState_SetFinalizing(_PyRuntimeState *runtime, PyThreadState *tstate) {
175    _Py_atomic_store_relaxed(&runtime->_finalizing, (uintptr_t)tstate);
176}
177
178#ifdef __cplusplus
179}
180#endif
181#endif /* !Py_INTERNAL_RUNTIME_H */
182