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
14/* ceval state */
15
16struct _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
29struct _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
46typedef struct _Py_AuditHookEntry {
47 struct _Py_AuditHookEntry *next;
48 Py_AuditHookFunction hookCFunction;
49 void *userData;
50} _Py_AuditHookEntry;
51
52struct _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
61typedef 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
128PyAPI_DATA(_PyRuntimeState) _PyRuntime;
129
130PyAPI_FUNC(PyStatus) _PyRuntimeState_Init(_PyRuntimeState *runtime);
131PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime);
132
133#ifdef HAVE_FORK
134extern PyStatus _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime);
135#endif
136
137/* Initialize _PyRuntimeState.
138 Return NULL on success, or return an error message on failure. */
139PyAPI_FUNC(PyStatus) _PyRuntime_Initialize(void);
140
141PyAPI_FUNC(void) _PyRuntime_Finalize(void);
142
143
144static inline PyThreadState*
145_PyRuntimeState_GetFinalizing(_PyRuntimeState *runtime) {
146 return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->_finalizing);
147}
148
149static inline void
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