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