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