1 #ifndef Py_INTERNAL_RUNTIME_H
2 #define Py_INTERNAL_RUNTIME_H
3 #ifdef __cplusplus
4 extern "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
14 /* ceval state */
15
16 struct _ceval_runtime_state {
17 /* Request for checking signals. It is shared by all interpreters (see
18 bpo-40513). Any thread of any interpreter can receive a signal, but only
19 the main thread of the main interpreter can handle signals: see
20 _Py_ThreadCanHandleSignals(). */
21 _Py_atomic_int signals_pending;
22 #ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
23 struct _gil_runtime_state gil;
24 #endif
25 };
26
27 /* GIL state */
28
29 struct _gilstate_runtime_state {
30 /* bpo-26558: Flag to disable PyGILState_Check().
31 If set to non-zero, PyGILState_Check() always return 1. */
32 int check_enabled;
33 /* Assuming the current thread holds the GIL, this is the
34 PyThreadState for the current thread. */
35 _Py_atomic_address tstate_current;
36 /* The single PyInterpreterState used by this process'
37 GILState implementation
38 */
39 /* TODO: Given interp_main, it may be possible to kill this ref */
40 PyInterpreterState *autoInterpreterState;
41 Py_tss_t autoTSSkey;
42 };
43
44 /* Runtime audit hook state */
45
46 typedef struct _Py_AuditHookEntry {
47 struct _Py_AuditHookEntry *next;
48 Py_AuditHookFunction hookCFunction;
49 void *userData;
50 } _Py_AuditHookEntry;
51
52 struct _Py_unicode_runtime_ids {
53 PyThread_type_lock lock;
54 // next_index value must be preserved when Py_Initialize()/Py_Finalize()
55 // is called multiple times: see _PyUnicode_FromId() implementation.
56 Py_ssize_t next_index;
57 };
58
59 /* Full Python runtime state */
60
61 typedef struct pyruntimestate {
62 /* Is running Py_PreInitialize()? */
63 int preinitializing;
64
65 /* Is Python preinitialized? Set to 1 by Py_PreInitialize() */
66 int preinitialized;
67
68 /* Is Python core initialized? Set to 1 by _Py_InitializeCore() */
69 int core_initialized;
70
71 /* Is Python fully initialized? Set to 1 by Py_Initialize() */
72 int initialized;
73
74 /* Set by Py_FinalizeEx(). Only reset to NULL if Py_Initialize()
75 is called again.
76
77 Use _PyRuntimeState_GetFinalizing() and _PyRuntimeState_SetFinalizing()
78 to access it, don't access it directly. */
79 _Py_atomic_address _finalizing;
80
81 struct pyinterpreters {
82 PyThread_type_lock mutex;
83 PyInterpreterState *head;
84 PyInterpreterState *main;
85 /* _next_interp_id is an auto-numbered sequence of small
86 integers. It gets initialized in _PyInterpreterState_Init(),
87 which is called in Py_Initialize(), and used in
88 PyInterpreterState_New(). A negative interpreter ID
89 indicates an error occurred. The main interpreter will
90 always have an ID of 0. Overflow results in a RuntimeError.
91 If that becomes a problem later then we can adjust, e.g. by
92 using a Python int. */
93 int64_t next_id;
94 } interpreters;
95 // XXX Remove this field once we have a tp_* slot.
96 struct _xidregistry {
97 PyThread_type_lock mutex;
98 struct _xidregitem *head;
99 } xidregistry;
100
101 unsigned long main_thread;
102
103 #define NEXITFUNCS 32
104 void (*exitfuncs[NEXITFUNCS])(void);
105 int nexitfuncs;
106
107 struct _ceval_runtime_state ceval;
108 struct _gilstate_runtime_state gilstate;
109
110 PyPreConfig preconfig;
111
112 // Audit values must be preserved when Py_Initialize()/Py_Finalize()
113 // is called multiple times.
114 Py_OpenCodeHookFunction open_code_hook;
115 void *open_code_userdata;
116 _Py_AuditHookEntry *audit_hook_head;
117
118 struct _Py_unicode_runtime_ids unicode_ids;
119
120 // XXX Consolidate globals found via the check-c-globals script.
121 } _PyRuntimeState;
122
123 #define _PyRuntimeState_INIT \
124 {.preinitialized = 0, .core_initialized = 0, .initialized = 0}
125 /* Note: _PyRuntimeState_INIT sets other fields to 0/NULL */
126
127
128 PyAPI_DATA(_PyRuntimeState) _PyRuntime;
129
130 PyAPI_FUNC(PyStatus) _PyRuntimeState_Init(_PyRuntimeState *runtime);
131 PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime);
132
133 #ifdef HAVE_FORK
134 extern PyStatus _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime);
135 #endif
136
137 /* Initialize _PyRuntimeState.
138 Return NULL on success, or return an error message on failure. */
139 PyAPI_FUNC(PyStatus) _PyRuntime_Initialize(void);
140
141 PyAPI_FUNC(void) _PyRuntime_Finalize(void);
142
143
144 static inline PyThreadState*
_PyRuntimeState_GetFinalizing(_PyRuntimeState * runtime)145 _PyRuntimeState_GetFinalizing(_PyRuntimeState *runtime) {
146 return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->_finalizing);
147 }
148
149 static inline void
_PyRuntimeState_SetFinalizing(_PyRuntimeState * runtime,PyThreadState * tstate)150 _PyRuntimeState_SetFinalizing(_PyRuntimeState *runtime, PyThreadState *tstate) {
151 _Py_atomic_store_relaxed(&runtime->_finalizing, (uintptr_t)tstate);
152 }
153
154 #ifdef __cplusplus
155 }
156 #endif
157 #endif /* !Py_INTERNAL_RUNTIME_H */
158