17db96d56Sopenharmony_ci#ifndef Py_INTERNAL_RUNTIME_H
27db96d56Sopenharmony_ci#define Py_INTERNAL_RUNTIME_H
37db96d56Sopenharmony_ci#ifdef __cplusplus
47db96d56Sopenharmony_ciextern "C" {
57db96d56Sopenharmony_ci#endif
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ci#ifndef Py_BUILD_CORE
87db96d56Sopenharmony_ci#  error "this header requires Py_BUILD_CORE define"
97db96d56Sopenharmony_ci#endif
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ci#include "pycore_atomic.h"          /* _Py_atomic_address */
127db96d56Sopenharmony_ci#include "pycore_gil.h"             // struct _gil_runtime_state
137db96d56Sopenharmony_ci#include "pycore_global_objects.h"  // struct _Py_global_objects
147db96d56Sopenharmony_ci#include "pycore_interp.h"          // PyInterpreterState
157db96d56Sopenharmony_ci#include "pycore_unicodeobject.h"   // struct _Py_unicode_runtime_ids
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_ci/* ceval state */
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_cistruct _ceval_runtime_state {
217db96d56Sopenharmony_ci    /* Request for checking signals. It is shared by all interpreters (see
227db96d56Sopenharmony_ci       bpo-40513). Any thread of any interpreter can receive a signal, but only
237db96d56Sopenharmony_ci       the main thread of the main interpreter can handle signals: see
247db96d56Sopenharmony_ci       _Py_ThreadCanHandleSignals(). */
257db96d56Sopenharmony_ci    _Py_atomic_int signals_pending;
267db96d56Sopenharmony_ci    struct _gil_runtime_state gil;
277db96d56Sopenharmony_ci};
287db96d56Sopenharmony_ci
297db96d56Sopenharmony_ci/* GIL state */
307db96d56Sopenharmony_ci
317db96d56Sopenharmony_cistruct _gilstate_runtime_state {
327db96d56Sopenharmony_ci    /* bpo-26558: Flag to disable PyGILState_Check().
337db96d56Sopenharmony_ci       If set to non-zero, PyGILState_Check() always return 1. */
347db96d56Sopenharmony_ci    int check_enabled;
357db96d56Sopenharmony_ci    /* Assuming the current thread holds the GIL, this is the
367db96d56Sopenharmony_ci       PyThreadState for the current thread. */
377db96d56Sopenharmony_ci    _Py_atomic_address tstate_current;
387db96d56Sopenharmony_ci    /* The single PyInterpreterState used by this process'
397db96d56Sopenharmony_ci       GILState implementation
407db96d56Sopenharmony_ci    */
417db96d56Sopenharmony_ci    /* TODO: Given interp_main, it may be possible to kill this ref */
427db96d56Sopenharmony_ci    PyInterpreterState *autoInterpreterState;
437db96d56Sopenharmony_ci    Py_tss_t autoTSSkey;
447db96d56Sopenharmony_ci};
457db96d56Sopenharmony_ci
467db96d56Sopenharmony_ci/* Runtime audit hook state */
477db96d56Sopenharmony_ci
487db96d56Sopenharmony_citypedef struct _Py_AuditHookEntry {
497db96d56Sopenharmony_ci    struct _Py_AuditHookEntry *next;
507db96d56Sopenharmony_ci    Py_AuditHookFunction hookCFunction;
517db96d56Sopenharmony_ci    void *userData;
527db96d56Sopenharmony_ci} _Py_AuditHookEntry;
537db96d56Sopenharmony_ci
547db96d56Sopenharmony_ci/* Full Python runtime state */
557db96d56Sopenharmony_ci
567db96d56Sopenharmony_ci/* _PyRuntimeState holds the global state for the CPython runtime.
577db96d56Sopenharmony_ci   That data is exposed in the internal API as a static variable (_PyRuntime).
587db96d56Sopenharmony_ci   */
597db96d56Sopenharmony_citypedef struct pyruntimestate {
607db96d56Sopenharmony_ci    /* Has been initialized to a safe state.
617db96d56Sopenharmony_ci
627db96d56Sopenharmony_ci       In order to be effective, this must be set to 0 during or right
637db96d56Sopenharmony_ci       after allocation. */
647db96d56Sopenharmony_ci    int _initialized;
657db96d56Sopenharmony_ci
667db96d56Sopenharmony_ci    /* Is running Py_PreInitialize()? */
677db96d56Sopenharmony_ci    int preinitializing;
687db96d56Sopenharmony_ci
697db96d56Sopenharmony_ci    /* Is Python preinitialized? Set to 1 by Py_PreInitialize() */
707db96d56Sopenharmony_ci    int preinitialized;
717db96d56Sopenharmony_ci
727db96d56Sopenharmony_ci    /* Is Python core initialized? Set to 1 by _Py_InitializeCore() */
737db96d56Sopenharmony_ci    int core_initialized;
747db96d56Sopenharmony_ci
757db96d56Sopenharmony_ci    /* Is Python fully initialized? Set to 1 by Py_Initialize() */
767db96d56Sopenharmony_ci    int initialized;
777db96d56Sopenharmony_ci
787db96d56Sopenharmony_ci    /* Set by Py_FinalizeEx(). Only reset to NULL if Py_Initialize()
797db96d56Sopenharmony_ci       is called again.
807db96d56Sopenharmony_ci
817db96d56Sopenharmony_ci       Use _PyRuntimeState_GetFinalizing() and _PyRuntimeState_SetFinalizing()
827db96d56Sopenharmony_ci       to access it, don't access it directly. */
837db96d56Sopenharmony_ci    _Py_atomic_address _finalizing;
847db96d56Sopenharmony_ci
857db96d56Sopenharmony_ci    struct pyinterpreters {
867db96d56Sopenharmony_ci        PyThread_type_lock mutex;
877db96d56Sopenharmony_ci        /* The linked list of interpreters, newest first. */
887db96d56Sopenharmony_ci        PyInterpreterState *head;
897db96d56Sopenharmony_ci        /* The runtime's initial interpreter, which has a special role
907db96d56Sopenharmony_ci           in the operation of the runtime.  It is also often the only
917db96d56Sopenharmony_ci           interpreter. */
927db96d56Sopenharmony_ci        PyInterpreterState *main;
937db96d56Sopenharmony_ci        /* _next_interp_id is an auto-numbered sequence of small
947db96d56Sopenharmony_ci           integers.  It gets initialized in _PyInterpreterState_Init(),
957db96d56Sopenharmony_ci           which is called in Py_Initialize(), and used in
967db96d56Sopenharmony_ci           PyInterpreterState_New().  A negative interpreter ID
977db96d56Sopenharmony_ci           indicates an error occurred.  The main interpreter will
987db96d56Sopenharmony_ci           always have an ID of 0.  Overflow results in a RuntimeError.
997db96d56Sopenharmony_ci           If that becomes a problem later then we can adjust, e.g. by
1007db96d56Sopenharmony_ci           using a Python int. */
1017db96d56Sopenharmony_ci        int64_t next_id;
1027db96d56Sopenharmony_ci    } interpreters;
1037db96d56Sopenharmony_ci    // XXX Remove this field once we have a tp_* slot.
1047db96d56Sopenharmony_ci    struct _xidregistry {
1057db96d56Sopenharmony_ci        PyThread_type_lock mutex;
1067db96d56Sopenharmony_ci        struct _xidregitem *head;
1077db96d56Sopenharmony_ci    } xidregistry;
1087db96d56Sopenharmony_ci
1097db96d56Sopenharmony_ci    unsigned long main_thread;
1107db96d56Sopenharmony_ci
1117db96d56Sopenharmony_ci#define NEXITFUNCS 32
1127db96d56Sopenharmony_ci    void (*exitfuncs[NEXITFUNCS])(void);
1137db96d56Sopenharmony_ci    int nexitfuncs;
1147db96d56Sopenharmony_ci
1157db96d56Sopenharmony_ci    struct _ceval_runtime_state ceval;
1167db96d56Sopenharmony_ci    struct _gilstate_runtime_state gilstate;
1177db96d56Sopenharmony_ci
1187db96d56Sopenharmony_ci    PyPreConfig preconfig;
1197db96d56Sopenharmony_ci
1207db96d56Sopenharmony_ci    // Audit values must be preserved when Py_Initialize()/Py_Finalize()
1217db96d56Sopenharmony_ci    // is called multiple times.
1227db96d56Sopenharmony_ci    Py_OpenCodeHookFunction open_code_hook;
1237db96d56Sopenharmony_ci    void *open_code_userdata;
1247db96d56Sopenharmony_ci    _Py_AuditHookEntry *audit_hook_head;
1257db96d56Sopenharmony_ci
1267db96d56Sopenharmony_ci    struct _Py_unicode_runtime_ids unicode_ids;
1277db96d56Sopenharmony_ci
1287db96d56Sopenharmony_ci    /* All the objects that are shared by the runtime's interpreters. */
1297db96d56Sopenharmony_ci    struct _Py_global_objects global_objects;
1307db96d56Sopenharmony_ci
1317db96d56Sopenharmony_ci    /* The following fields are here to avoid allocation during init.
1327db96d56Sopenharmony_ci       The data is exposed through _PyRuntimeState pointer fields.
1337db96d56Sopenharmony_ci       These fields should not be accessed directly outside of init.
1347db96d56Sopenharmony_ci
1357db96d56Sopenharmony_ci       All other _PyRuntimeState pointer fields are populated when
1367db96d56Sopenharmony_ci       needed and default to NULL.
1377db96d56Sopenharmony_ci
1387db96d56Sopenharmony_ci       For now there are some exceptions to that rule, which require
1397db96d56Sopenharmony_ci       allocation during init.  These will be addressed on a case-by-case
1407db96d56Sopenharmony_ci       basis.  Most notably, we don't pre-allocated the several mutex
1417db96d56Sopenharmony_ci       (PyThread_type_lock) fields, because on Windows we only ever get
1427db96d56Sopenharmony_ci       a pointer type.
1437db96d56Sopenharmony_ci       */
1447db96d56Sopenharmony_ci
1457db96d56Sopenharmony_ci    /* PyInterpreterState.interpreters.main */
1467db96d56Sopenharmony_ci    PyInterpreterState _main_interpreter;
1477db96d56Sopenharmony_ci} _PyRuntimeState;
1487db96d56Sopenharmony_ci
1497db96d56Sopenharmony_ci
1507db96d56Sopenharmony_ci/* other API */
1517db96d56Sopenharmony_ci
1527db96d56Sopenharmony_ciPyAPI_DATA(_PyRuntimeState) _PyRuntime;
1537db96d56Sopenharmony_ci
1547db96d56Sopenharmony_ciPyAPI_FUNC(PyStatus) _PyRuntimeState_Init(_PyRuntimeState *runtime);
1557db96d56Sopenharmony_ciPyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime);
1567db96d56Sopenharmony_ci
1577db96d56Sopenharmony_ci#ifdef HAVE_FORK
1587db96d56Sopenharmony_ciextern PyStatus _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime);
1597db96d56Sopenharmony_ci#endif
1607db96d56Sopenharmony_ci
1617db96d56Sopenharmony_ci/* Initialize _PyRuntimeState.
1627db96d56Sopenharmony_ci   Return NULL on success, or return an error message on failure. */
1637db96d56Sopenharmony_ciPyAPI_FUNC(PyStatus) _PyRuntime_Initialize(void);
1647db96d56Sopenharmony_ci
1657db96d56Sopenharmony_ciPyAPI_FUNC(void) _PyRuntime_Finalize(void);
1667db96d56Sopenharmony_ci
1677db96d56Sopenharmony_ci
1687db96d56Sopenharmony_cistatic inline PyThreadState*
1697db96d56Sopenharmony_ci_PyRuntimeState_GetFinalizing(_PyRuntimeState *runtime) {
1707db96d56Sopenharmony_ci    return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->_finalizing);
1717db96d56Sopenharmony_ci}
1727db96d56Sopenharmony_ci
1737db96d56Sopenharmony_cistatic inline void
1747db96d56Sopenharmony_ci_PyRuntimeState_SetFinalizing(_PyRuntimeState *runtime, PyThreadState *tstate) {
1757db96d56Sopenharmony_ci    _Py_atomic_store_relaxed(&runtime->_finalizing, (uintptr_t)tstate);
1767db96d56Sopenharmony_ci}
1777db96d56Sopenharmony_ci
1787db96d56Sopenharmony_ci#ifdef __cplusplus
1797db96d56Sopenharmony_ci}
1807db96d56Sopenharmony_ci#endif
1817db96d56Sopenharmony_ci#endif /* !Py_INTERNAL_RUNTIME_H */
182