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* |
145 | _PyRuntimeState_GetFinalizing(_PyRuntimeState *runtime) { |
146 | return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->_finalizing); |
147 | } |
148 | |
149 | static 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 | |