mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	bpo-40268: Add pycore_runtime.h header file (GH-19493)
Move PyRuntimeState from pycore_pystate.h to pycore_runtime.h. Remove _PyGILState_check_enabled macro: access directly _PyRuntime.gilstate.check_enabled.
This commit is contained in:
		
							parent
							
								
									0135598d72
								
							
						
					
					
						commit
						1c4cbdf94d
					
				
					 7 changed files with 152 additions and 125 deletions
				
			
		|  | @ -11,6 +11,7 @@ extern "C" { | ||||||
| #include "pycore_gil.h"       /* struct _gil_runtime_state  */ | #include "pycore_gil.h"       /* struct _gil_runtime_state  */ | ||||||
| #include "pycore_pymem.h"     /* struct _gc_runtime_state */ | #include "pycore_pymem.h"     /* struct _gc_runtime_state */ | ||||||
| #include "pycore_warnings.h"  /* struct _warnings_runtime_state */ | #include "pycore_warnings.h"  /* struct _warnings_runtime_state */ | ||||||
|  | #include "pycore_runtime.h"   /* PyRuntimestate */ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* ceval state */ | /* ceval state */ | ||||||
|  | @ -32,15 +33,6 @@ struct _pending_calls { | ||||||
|     int last; |     int last; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct _ceval_runtime_state { |  | ||||||
|     int recursion_limit; |  | ||||||
|     /* Request for dropping the GIL */ |  | ||||||
|     _Py_atomic_int gil_drop_request; |  | ||||||
|     /* Request for checking signals. */ |  | ||||||
|     _Py_atomic_int signals_pending; |  | ||||||
|     struct _gil_runtime_state gil; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct _ceval_state { | struct _ceval_state { | ||||||
|     /* Records whether tracing is on for any thread.  Counts the number
 |     /* Records whether tracing is on for any thread.  Counts the number
 | ||||||
|        of threads for which tstate->c_tracefunc is non-NULL, so if the |        of threads for which tstate->c_tracefunc is non-NULL, so if the | ||||||
|  | @ -176,118 +168,6 @@ struct _xidregitem { | ||||||
|     struct _xidregitem *next; |     struct _xidregitem *next; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* runtime audit hook state */ |  | ||||||
| 
 |  | ||||||
| typedef struct _Py_AuditHookEntry { |  | ||||||
|     struct _Py_AuditHookEntry *next; |  | ||||||
|     Py_AuditHookFunction hookCFunction; |  | ||||||
|     void *userData; |  | ||||||
| } _Py_AuditHookEntry; |  | ||||||
| 
 |  | ||||||
| /* GIL state */ |  | ||||||
| 
 |  | ||||||
| struct _gilstate_runtime_state { |  | ||||||
|     int check_enabled; |  | ||||||
|     /* Assuming the current thread holds the GIL, this is the
 |  | ||||||
|        PyThreadState for the current thread. */ |  | ||||||
|     _Py_atomic_address tstate_current; |  | ||||||
|     /* The single PyInterpreterState used by this process'
 |  | ||||||
|        GILState implementation |  | ||||||
|     */ |  | ||||||
|     /* TODO: Given interp_main, it may be possible to kill this ref */ |  | ||||||
|     PyInterpreterState *autoInterpreterState; |  | ||||||
|     Py_tss_t autoTSSkey; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /* Issue #26558: Flag to disable PyGILState_Check().
 |  | ||||||
|    If set to non-zero, PyGILState_Check() always return 1. */ |  | ||||||
| #define _PyGILState_check_enabled _PyRuntime.gilstate.check_enabled |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /* Full Python runtime state */ |  | ||||||
| 
 |  | ||||||
| typedef struct pyruntimestate { |  | ||||||
|     /* Is running Py_PreInitialize()? */ |  | ||||||
|     int preinitializing; |  | ||||||
| 
 |  | ||||||
|     /* Is Python preinitialized? Set to 1 by Py_PreInitialize() */ |  | ||||||
|     int preinitialized; |  | ||||||
| 
 |  | ||||||
|     /* Is Python core initialized? Set to 1 by _Py_InitializeCore() */ |  | ||||||
|     int core_initialized; |  | ||||||
| 
 |  | ||||||
|     /* Is Python fully initialized? Set to 1 by Py_Initialize() */ |  | ||||||
|     int initialized; |  | ||||||
| 
 |  | ||||||
|     /* Set by Py_FinalizeEx(). Only reset to NULL if Py_Initialize()
 |  | ||||||
|        is called again. |  | ||||||
| 
 |  | ||||||
|        Use _PyRuntimeState_GetFinalizing() and _PyRuntimeState_SetFinalizing() |  | ||||||
|        to access it, don't access it directly. */ |  | ||||||
|     _Py_atomic_address _finalizing; |  | ||||||
| 
 |  | ||||||
|     struct pyinterpreters { |  | ||||||
|         PyThread_type_lock mutex; |  | ||||||
|         PyInterpreterState *head; |  | ||||||
|         PyInterpreterState *main; |  | ||||||
|         /* _next_interp_id is an auto-numbered sequence of small
 |  | ||||||
|            integers.  It gets initialized in _PyInterpreterState_Init(), |  | ||||||
|            which is called in Py_Initialize(), and used in |  | ||||||
|            PyInterpreterState_New().  A negative interpreter ID |  | ||||||
|            indicates an error occurred.  The main interpreter will |  | ||||||
|            always have an ID of 0.  Overflow results in a RuntimeError. |  | ||||||
|            If that becomes a problem later then we can adjust, e.g. by |  | ||||||
|            using a Python int. */ |  | ||||||
|         int64_t next_id; |  | ||||||
|     } interpreters; |  | ||||||
|     // XXX Remove this field once we have a tp_* slot.
 |  | ||||||
|     struct _xidregistry { |  | ||||||
|         PyThread_type_lock mutex; |  | ||||||
|         struct _xidregitem *head; |  | ||||||
|     } xidregistry; |  | ||||||
| 
 |  | ||||||
|     unsigned long main_thread; |  | ||||||
| 
 |  | ||||||
| #define NEXITFUNCS 32 |  | ||||||
|     void (*exitfuncs[NEXITFUNCS])(void); |  | ||||||
|     int nexitfuncs; |  | ||||||
| 
 |  | ||||||
|     struct _ceval_runtime_state ceval; |  | ||||||
|     struct _gilstate_runtime_state gilstate; |  | ||||||
| 
 |  | ||||||
|     PyPreConfig preconfig; |  | ||||||
| 
 |  | ||||||
|     Py_OpenCodeHookFunction open_code_hook; |  | ||||||
|     void *open_code_userdata; |  | ||||||
|     _Py_AuditHookEntry *audit_hook_head; |  | ||||||
| 
 |  | ||||||
|     // XXX Consolidate globals found via the check-c-globals script.
 |  | ||||||
| } _PyRuntimeState; |  | ||||||
| 
 |  | ||||||
| #define _PyRuntimeState_INIT \ |  | ||||||
|     {.preinitialized = 0, .core_initialized = 0, .initialized = 0} |  | ||||||
| /* Note: _PyRuntimeState_INIT sets other fields to 0/NULL */ |  | ||||||
| 
 |  | ||||||
| PyAPI_DATA(_PyRuntimeState) _PyRuntime; |  | ||||||
| PyAPI_FUNC(PyStatus) _PyRuntimeState_Init(_PyRuntimeState *runtime); |  | ||||||
| PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime); |  | ||||||
| PyAPI_FUNC(void) _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime); |  | ||||||
| 
 |  | ||||||
| /* Initialize _PyRuntimeState.
 |  | ||||||
|    Return NULL on success, or return an error message on failure. */ |  | ||||||
| PyAPI_FUNC(PyStatus) _PyRuntime_Initialize(void); |  | ||||||
| 
 |  | ||||||
| PyAPI_FUNC(void) _PyRuntime_Finalize(void); |  | ||||||
| 
 |  | ||||||
| static inline PyThreadState* |  | ||||||
| _PyRuntimeState_GetFinalizing(_PyRuntimeState *runtime) { |  | ||||||
|     return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->_finalizing); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline void |  | ||||||
| _PyRuntimeState_SetFinalizing(_PyRuntimeState *runtime, PyThreadState *tstate) { |  | ||||||
|     _Py_atomic_store_relaxed(&runtime->_finalizing, (uintptr_t)tstate); |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| /* Check if the current thread is the main thread.
 | /* Check if the current thread is the main thread.
 | ||||||
|    Use _Py_IsMainInterpreter() to check if it's the main interpreter. */ |    Use _Py_IsMainInterpreter() to check if it's the main interpreter. */ | ||||||
|  |  | ||||||
							
								
								
									
										143
									
								
								Include/internal/pycore_runtime.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								Include/internal/pycore_runtime.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,143 @@ | ||||||
|  | #ifndef Py_INTERNAL_RUNTIME_H | ||||||
|  | #define Py_INTERNAL_RUNTIME_H | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef Py_BUILD_CORE | ||||||
|  | #  error "this header requires Py_BUILD_CORE define" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #include "pycore_atomic.h"    /* _Py_atomic_address */ | ||||||
|  | #include "pycore_gil.h"       // struct _gil_runtime_state | ||||||
|  | 
 | ||||||
|  | /* ceval state */ | ||||||
|  | 
 | ||||||
|  | struct _ceval_runtime_state { | ||||||
|  |     int recursion_limit; | ||||||
|  |     /* Request for dropping the GIL */ | ||||||
|  |     _Py_atomic_int gil_drop_request; | ||||||
|  |     /* Request for checking signals. */ | ||||||
|  |     _Py_atomic_int signals_pending; | ||||||
|  |     struct _gil_runtime_state gil; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* GIL state */ | ||||||
|  | 
 | ||||||
|  | struct _gilstate_runtime_state { | ||||||
|  |     /* bpo-26558: Flag to disable PyGILState_Check().
 | ||||||
|  |        If set to non-zero, PyGILState_Check() always return 1. */ | ||||||
|  |     int check_enabled; | ||||||
|  |     /* Assuming the current thread holds the GIL, this is the
 | ||||||
|  |        PyThreadState for the current thread. */ | ||||||
|  |     _Py_atomic_address tstate_current; | ||||||
|  |     /* The single PyInterpreterState used by this process'
 | ||||||
|  |        GILState implementation | ||||||
|  |     */ | ||||||
|  |     /* TODO: Given interp_main, it may be possible to kill this ref */ | ||||||
|  |     PyInterpreterState *autoInterpreterState; | ||||||
|  |     Py_tss_t autoTSSkey; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* Runtime audit hook state */ | ||||||
|  | 
 | ||||||
|  | typedef struct _Py_AuditHookEntry { | ||||||
|  |     struct _Py_AuditHookEntry *next; | ||||||
|  |     Py_AuditHookFunction hookCFunction; | ||||||
|  |     void *userData; | ||||||
|  | } _Py_AuditHookEntry; | ||||||
|  | 
 | ||||||
|  | /* Full Python runtime state */ | ||||||
|  | 
 | ||||||
|  | typedef struct pyruntimestate { | ||||||
|  |     /* Is running Py_PreInitialize()? */ | ||||||
|  |     int preinitializing; | ||||||
|  | 
 | ||||||
|  |     /* Is Python preinitialized? Set to 1 by Py_PreInitialize() */ | ||||||
|  |     int preinitialized; | ||||||
|  | 
 | ||||||
|  |     /* Is Python core initialized? Set to 1 by _Py_InitializeCore() */ | ||||||
|  |     int core_initialized; | ||||||
|  | 
 | ||||||
|  |     /* Is Python fully initialized? Set to 1 by Py_Initialize() */ | ||||||
|  |     int initialized; | ||||||
|  | 
 | ||||||
|  |     /* Set by Py_FinalizeEx(). Only reset to NULL if Py_Initialize()
 | ||||||
|  |        is called again. | ||||||
|  | 
 | ||||||
|  |        Use _PyRuntimeState_GetFinalizing() and _PyRuntimeState_SetFinalizing() | ||||||
|  |        to access it, don't access it directly. */ | ||||||
|  |     _Py_atomic_address _finalizing; | ||||||
|  | 
 | ||||||
|  |     struct pyinterpreters { | ||||||
|  |         PyThread_type_lock mutex; | ||||||
|  |         PyInterpreterState *head; | ||||||
|  |         PyInterpreterState *main; | ||||||
|  |         /* _next_interp_id is an auto-numbered sequence of small
 | ||||||
|  |            integers.  It gets initialized in _PyInterpreterState_Init(), | ||||||
|  |            which is called in Py_Initialize(), and used in | ||||||
|  |            PyInterpreterState_New().  A negative interpreter ID | ||||||
|  |            indicates an error occurred.  The main interpreter will | ||||||
|  |            always have an ID of 0.  Overflow results in a RuntimeError. | ||||||
|  |            If that becomes a problem later then we can adjust, e.g. by | ||||||
|  |            using a Python int. */ | ||||||
|  |         int64_t next_id; | ||||||
|  |     } interpreters; | ||||||
|  |     // XXX Remove this field once we have a tp_* slot.
 | ||||||
|  |     struct _xidregistry { | ||||||
|  |         PyThread_type_lock mutex; | ||||||
|  |         struct _xidregitem *head; | ||||||
|  |     } xidregistry; | ||||||
|  | 
 | ||||||
|  |     unsigned long main_thread; | ||||||
|  | 
 | ||||||
|  | #define NEXITFUNCS 32 | ||||||
|  |     void (*exitfuncs[NEXITFUNCS])(void); | ||||||
|  |     int nexitfuncs; | ||||||
|  | 
 | ||||||
|  |     struct _ceval_runtime_state ceval; | ||||||
|  |     struct _gilstate_runtime_state gilstate; | ||||||
|  | 
 | ||||||
|  |     PyPreConfig preconfig; | ||||||
|  | 
 | ||||||
|  |     Py_OpenCodeHookFunction open_code_hook; | ||||||
|  |     void *open_code_userdata; | ||||||
|  |     _Py_AuditHookEntry *audit_hook_head; | ||||||
|  | 
 | ||||||
|  |     // XXX Consolidate globals found via the check-c-globals script.
 | ||||||
|  | } _PyRuntimeState; | ||||||
|  | 
 | ||||||
|  | #define _PyRuntimeState_INIT \ | ||||||
|  |     {.preinitialized = 0, .core_initialized = 0, .initialized = 0} | ||||||
|  | /* Note: _PyRuntimeState_INIT sets other fields to 0/NULL */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | PyAPI_DATA(_PyRuntimeState) _PyRuntime; | ||||||
|  | 
 | ||||||
|  | PyAPI_FUNC(PyStatus) _PyRuntimeState_Init(_PyRuntimeState *runtime); | ||||||
|  | PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime); | ||||||
|  | 
 | ||||||
|  | PyAPI_FUNC(void) _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Initialize _PyRuntimeState.
 | ||||||
|  |    Return NULL on success, or return an error message on failure. */ | ||||||
|  | PyAPI_FUNC(PyStatus) _PyRuntime_Initialize(void); | ||||||
|  | 
 | ||||||
|  | PyAPI_FUNC(void) _PyRuntime_Finalize(void); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static inline PyThreadState* | ||||||
|  | _PyRuntimeState_GetFinalizing(_PyRuntimeState *runtime) { | ||||||
|  |     return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->_finalizing); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline void | ||||||
|  | _PyRuntimeState_SetFinalizing(_PyRuntimeState *runtime, PyThreadState *tstate) { | ||||||
|  |     _Py_atomic_store_relaxed(&runtime->_finalizing, (uintptr_t)tstate); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | #endif /* !Py_INTERNAL_RUNTIME_H */ | ||||||
|  | @ -1103,6 +1103,7 @@ PYTHON_HEADERS= \ | ||||||
| 		$(srcdir)/Include/internal/pycore_pylifecycle.h \ | 		$(srcdir)/Include/internal/pycore_pylifecycle.h \ | ||||||
| 		$(srcdir)/Include/internal/pycore_pymem.h \ | 		$(srcdir)/Include/internal/pycore_pymem.h \ | ||||||
| 		$(srcdir)/Include/internal/pycore_pystate.h \ | 		$(srcdir)/Include/internal/pycore_pystate.h \ | ||||||
|  | 		$(srcdir)/Include/internal/pycore_runtime.h \ | ||||||
| 		$(srcdir)/Include/internal/pycore_sysmodule.h \ | 		$(srcdir)/Include/internal/pycore_sysmodule.h \ | ||||||
| 		$(srcdir)/Include/internal/pycore_traceback.h \ | 		$(srcdir)/Include/internal/pycore_traceback.h \ | ||||||
| 		$(srcdir)/Include/internal/pycore_tupleobject.h \ | 		$(srcdir)/Include/internal/pycore_tupleobject.h \ | ||||||
|  |  | ||||||
|  | @ -184,6 +184,7 @@ | ||||||
|     <ClInclude Include="..\Include\internal\pycore_pylifecycle.h" /> |     <ClInclude Include="..\Include\internal\pycore_pylifecycle.h" /> | ||||||
|     <ClInclude Include="..\Include\internal\pycore_pymem.h" /> |     <ClInclude Include="..\Include\internal\pycore_pymem.h" /> | ||||||
|     <ClInclude Include="..\Include\internal\pycore_pystate.h" /> |     <ClInclude Include="..\Include\internal\pycore_pystate.h" /> | ||||||
|  |     <ClInclude Include="..\Include\internal\pycore_runtime.h" /> | ||||||
|     <ClInclude Include="..\Include\internal\pycore_sysmodule.h" /> |     <ClInclude Include="..\Include\internal\pycore_sysmodule.h" /> | ||||||
|     <ClInclude Include="..\Include\internal\pycore_traceback.h" /> |     <ClInclude Include="..\Include\internal\pycore_traceback.h" /> | ||||||
|     <ClInclude Include="..\Include\internal\pycore_tupleobject.h" /> |     <ClInclude Include="..\Include\internal\pycore_tupleobject.h" /> | ||||||
|  |  | ||||||
|  | @ -255,6 +255,9 @@ | ||||||
|     <ClInclude Include="..\Include\internal\pycore_pystate.h"> |     <ClInclude Include="..\Include\internal\pycore_pystate.h"> | ||||||
|       <Filter>Include</Filter> |       <Filter>Include</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\Include\internal\pycore_runtime.h"> | ||||||
|  |       <Filter>Include</Filter> | ||||||
|  |     </ClInclude> | ||||||
|     <ClInclude Include="..\Include\internal\pycore_sysmodule.h"> |     <ClInclude Include="..\Include\internal\pycore_sysmodule.h"> | ||||||
|       <Filter>Include</Filter> |       <Filter>Include</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|  |  | ||||||
|  | @ -1553,7 +1553,7 @@ new_interpreter(PyThreadState **tstate_p) | ||||||
| 
 | 
 | ||||||
|     /* Issue #10915, #15751: The GIL API doesn't work with multiple
 |     /* Issue #10915, #15751: The GIL API doesn't work with multiple
 | ||||||
|        interpreters: disable PyGILState_Check(). */ |        interpreters: disable PyGILState_Check(). */ | ||||||
|     _PyGILState_check_enabled = 0; |     runtime->gilstate.check_enabled = 0; | ||||||
| 
 | 
 | ||||||
|     PyInterpreterState *interp = PyInterpreterState_New(); |     PyInterpreterState *interp = PyInterpreterState_New(); | ||||||
|     if (interp == NULL) { |     if (interp == NULL) { | ||||||
|  |  | ||||||
|  | @ -1329,12 +1329,11 @@ PyGILState_GetThisThreadState(void) | ||||||
| int | int | ||||||
| PyGILState_Check(void) | PyGILState_Check(void) | ||||||
| { | { | ||||||
| 
 |     struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; | ||||||
|     if (!_PyGILState_check_enabled) { |     if (!gilstate->check_enabled) { | ||||||
|         return 1; |         return 1; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; |  | ||||||
|     if (!PyThread_tss_is_created(&gilstate->autoTSSkey)) { |     if (!PyThread_tss_is_created(&gilstate->autoTSSkey)) { | ||||||
|         return 1; |         return 1; | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner