• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 int
_Py_IsMainInterpreter(PyThreadState * tstate)25 _Py_IsMainInterpreter(PyThreadState* tstate)
26 {
27     /* Use directly _PyRuntime rather than tstate->interp->runtime, since
28        this function is used in performance critical code path (ceval) */
29     return (tstate->interp == _PyRuntime.interpreters.main);
30 }
31 
32 
33 /* Only handle signals on the main thread of the main interpreter. */
34 static inline int
_Py_ThreadCanHandleSignals(PyInterpreterState * interp)35 _Py_ThreadCanHandleSignals(PyInterpreterState *interp)
36 {
37     return (_Py_IsMainThread() && interp == _PyRuntime.interpreters.main);
38 }
39 
40 
41 /* Only execute pending calls on the main thread. */
42 static inline int
_Py_ThreadCanHandlePendingCalls(void)43 _Py_ThreadCanHandlePendingCalls(void)
44 {
45     return _Py_IsMainThread();
46 }
47 
48 
49 /* Variable and macro for in-line access to current thread
50    and interpreter state */
51 
52 static inline PyThreadState*
_PyRuntimeState_GetThreadState(_PyRuntimeState * runtime)53 _PyRuntimeState_GetThreadState(_PyRuntimeState *runtime)
54 {
55     return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->gilstate.tstate_current);
56 }
57 
58 /* Get the current Python thread state.
59 
60    Efficient macro reading directly the 'gilstate.tstate_current' atomic
61    variable. The macro is unsafe: it does not check for error and it can
62    return NULL.
63 
64    The caller must hold the GIL.
65 
66    See also PyThreadState_Get() and PyThreadState_GET(). */
67 static inline PyThreadState*
_PyThreadState_GET(void)68 _PyThreadState_GET(void)
69 {
70     return _PyRuntimeState_GetThreadState(&_PyRuntime);
71 }
72 
73 /* Redefine PyThreadState_GET() as an alias to _PyThreadState_GET() */
74 #undef PyThreadState_GET
75 #define PyThreadState_GET() _PyThreadState_GET()
76 
77 PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalError_TstateNULL(const char *func);
78 
79 static inline void
_Py_EnsureFuncTstateNotNULL(const char * func,PyThreadState * tstate)80 _Py_EnsureFuncTstateNotNULL(const char *func, PyThreadState *tstate)
81 {
82     if (tstate == NULL) {
83         _Py_FatalError_TstateNULL(func);
84     }
85 }
86 
87 // Call Py_FatalError() if tstate is NULL
88 #define _Py_EnsureTstateNotNULL(tstate) \
89     _Py_EnsureFuncTstateNotNULL(__func__, tstate)
90 
91 
92 /* Get the current interpreter state.
93 
94    The macro is unsafe: it does not check for error and it can return NULL.
95 
96    The caller must hold the GIL.
97 
98    See also _PyInterpreterState_Get()
99    and _PyGILState_GetInterpreterStateUnsafe(). */
_PyInterpreterState_GET(void)100 static inline PyInterpreterState* _PyInterpreterState_GET(void) {
101     PyThreadState *tstate = _PyThreadState_GET();
102 #ifdef Py_DEBUG
103     _Py_EnsureTstateNotNULL(tstate);
104 #endif
105     return tstate->interp;
106 }
107 
108 
109 /* Other */
110 
111 PyAPI_FUNC(void) _PyThreadState_Init(
112     PyThreadState *tstate);
113 PyAPI_FUNC(void) _PyThreadState_DeleteExcept(
114     _PyRuntimeState *runtime,
115     PyThreadState *tstate);
116 
117 PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap(
118     struct _gilstate_runtime_state *gilstate,
119     PyThreadState *newts);
120 
121 PyAPI_FUNC(PyStatus) _PyInterpreterState_Enable(_PyRuntimeState *runtime);
122 PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime);
123 
124 PyAPI_FUNC(void) _PyGILState_Reinit(_PyRuntimeState *runtime);
125 
126 
127 PyAPI_FUNC(int) _PyState_AddModule(
128     PyThreadState *tstate,
129     PyObject* module,
130     struct PyModuleDef* def);
131 
132 
133 PyAPI_FUNC(int) _PyOS_InterruptOccurred(PyThreadState *tstate);
134 
135 #ifdef __cplusplus
136 }
137 #endif
138 #endif /* !Py_INTERNAL_PYSTATE_H */
139