1 #ifndef Py_INTERNAL_PYSTATE_H
2 #define Py_INTERNAL_PYSTATE_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_runtime.h"   /* PyRuntimeState */
12 
13 
14 /* Check if the current thread is the main thread.
15    Use _Py_IsMainInterpreter() to check if it's the main interpreter. */
16 static inline int
_Py_IsMainThread(void)17 _Py_IsMainThread(void)
18 {
19     unsigned long thread = PyThread_get_thread_ident();
20     return (thread == _PyRuntime.main_thread);
21 }
22 
23 
24 static inline PyInterpreterState *
_PyInterpreterState_Main(void)25 _PyInterpreterState_Main(void)
26 {
27     return _PyRuntime.interpreters.main;
28 }
29 
30 static inline int
_Py_IsMainInterpreter(PyInterpreterState *interp)31 _Py_IsMainInterpreter(PyInterpreterState *interp)
32 {
33     return (interp == _PyInterpreterState_Main());
34 }
35 
36 
37 static inline const PyConfig *
_Py_GetMainConfig(void)38 _Py_GetMainConfig(void)
39 {
40     PyInterpreterState *interp = _PyInterpreterState_Main();
41     if (interp == NULL) {
42         return NULL;
43     }
44     return _PyInterpreterState_GetConfig(interp);
45 }
46 
47 
48 /* Only handle signals on the main thread of the main interpreter. */
49 static inline int
_Py_ThreadCanHandleSignals(PyInterpreterState *interp)50 _Py_ThreadCanHandleSignals(PyInterpreterState *interp)
51 {
52     return (_Py_IsMainThread() && _Py_IsMainInterpreter(interp));
53 }
54 
55 
56 /* Only execute pending calls on the main thread. */
57 static inline int
_Py_ThreadCanHandlePendingCalls(void)58 _Py_ThreadCanHandlePendingCalls(void)
59 {
60     return _Py_IsMainThread();
61 }
62 
63 
64 /* Variable and macro for in-line access to current thread
65    and interpreter state */
66 
67 static inline PyThreadState*
_PyRuntimeState_GetThreadState(_PyRuntimeState *runtime)68 _PyRuntimeState_GetThreadState(_PyRuntimeState *runtime)
69 {
70     return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->gilstate.tstate_current);
71 }
72 
73 /* Get the current Python thread state.
74 
75    Efficient macro reading directly the 'gilstate.tstate_current' atomic
76    variable. The macro is unsafe: it does not check for error and it can
77    return NULL.
78 
79    The caller must hold the GIL.
80 
81    See also PyThreadState_Get() and _PyThreadState_UncheckedGet(). */
82 static inline PyThreadState*
_PyThreadState_GET(void)83 _PyThreadState_GET(void)
84 {
85     return _PyRuntimeState_GetThreadState(&_PyRuntime);
86 }
87 
88 PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalError_TstateNULL(const char *func);
89 
90 static inline void
_Py_EnsureFuncTstateNotNULL(const char *func, PyThreadState *tstate)91 _Py_EnsureFuncTstateNotNULL(const char *func, PyThreadState *tstate)
92 {
93     if (tstate == NULL) {
94         _Py_FatalError_TstateNULL(func);
95     }
96 }
97 
98 // Call Py_FatalError() if tstate is NULL
99 #define _Py_EnsureTstateNotNULL(tstate) \
100     _Py_EnsureFuncTstateNotNULL(__func__, tstate)
101 
102 
103 /* Get the current interpreter state.
104 
105    The macro is unsafe: it does not check for error and it can return NULL.
106 
107    The caller must hold the GIL.
108 
109    See also _PyInterpreterState_Get()
110    and _PyGILState_GetInterpreterStateUnsafe(). */
_PyInterpreterState_GET(void)111 static inline PyInterpreterState* _PyInterpreterState_GET(void) {
112     PyThreadState *tstate = _PyThreadState_GET();
113 #ifdef Py_DEBUG
114     _Py_EnsureTstateNotNULL(tstate);
115 #endif
116     return tstate->interp;
117 }
118 
119 
120 // PyThreadState functions
121 
122 PyAPI_FUNC(void) _PyThreadState_SetCurrent(PyThreadState *tstate);
123 // We keep this around exclusively for stable ABI compatibility.
124 PyAPI_FUNC(void) _PyThreadState_Init(
125     PyThreadState *tstate);
126 PyAPI_FUNC(void) _PyThreadState_DeleteExcept(
127     _PyRuntimeState *runtime,
128     PyThreadState *tstate);
129 
130 
131 static inline void
_PyThreadState_UpdateTracingState(PyThreadState *tstate)132 _PyThreadState_UpdateTracingState(PyThreadState *tstate)
133 {
134     bool use_tracing =
135         (tstate->tracing == 0) &&
136         (tstate->c_tracefunc != NULL || tstate->c_profilefunc != NULL);
137     tstate->cframe->use_tracing = (use_tracing ? 255 : 0);
138 }
139 
140 
141 /* Other */
142 
143 PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap(
144     struct _gilstate_runtime_state *gilstate,
145     PyThreadState *newts);
146 
147 PyAPI_FUNC(PyStatus) _PyInterpreterState_Enable(_PyRuntimeState *runtime);
148 
149 #ifdef HAVE_FORK
150 extern PyStatus _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime);
151 extern PyStatus _PyGILState_Reinit(_PyRuntimeState *runtime);
152 extern void _PySignal_AfterFork(void);
153 #endif
154 
155 
156 PyAPI_FUNC(int) _PyState_AddModule(
157     PyThreadState *tstate,
158     PyObject* module,
159     PyModuleDef* def);
160 
161 
162 PyAPI_FUNC(int) _PyOS_InterruptOccurred(PyThreadState *tstate);
163 
164 #ifdef __cplusplus
165 }
166 #endif
167 #endif /* !Py_INTERNAL_PYSTATE_H */
168