• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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