mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	bpo-40522: _PyThreadState_Swap() sets autoTSSkey (GH-19939)
In the experimental isolated subinterpreters build mode, _PyThreadState_GET() gets the autoTSSkey variable and _PyThreadState_Swap() sets the autoTSSkey variable. * Add _PyThreadState_GetTSS() * _PyRuntimeState_GetThreadState() and _PyThreadState_GET() return _PyThreadState_GetTSS() * PyEval_SaveThread() sets the autoTSSkey variable to current Python thread state rather than NULL. * eval_frame_handle_pending() doesn't check that _PyThreadState_Swap() result is NULL. * _PyThreadState_Swap() gets the current Python thread state with _PyThreadState_GetTSS() rather than _PyRuntimeGILState_GetThreadState(). * PyGILState_Ensure() no longer checks _PyEval_ThreadsInitialized() since it cannot access the current interpreter.
This commit is contained in:
		
							parent
							
								
									b4b53868d7
								
							
						
					
					
						commit
						e838a9324c
					
				
					 3 changed files with 48 additions and 2 deletions
				
			
		|  | @ -49,8 +49,18 @@ _Py_ThreadCanHandlePendingCalls(void) | |||
| /* Variable and macro for in-line access to current thread
 | ||||
|    and interpreter state */ | ||||
| 
 | ||||
| static inline PyThreadState* _PyRuntimeState_GetThreadState(_PyRuntimeState *runtime) { | ||||
| #ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS | ||||
| PyAPI_FUNC(PyThreadState*) _PyThreadState_GetTSS(void); | ||||
| #endif | ||||
| 
 | ||||
| static inline PyThreadState* | ||||
| _PyRuntimeState_GetThreadState(_PyRuntimeState *runtime) | ||||
| { | ||||
| #ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS | ||||
|     return _PyThreadState_GetTSS(); | ||||
| #else | ||||
|     return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->gilstate.tstate_current); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| /* Get the current Python thread state.
 | ||||
|  | @ -62,8 +72,14 @@ static inline PyThreadState* _PyRuntimeState_GetThreadState(_PyRuntimeState *run | |||
|    The caller must hold the GIL. | ||||
| 
 | ||||
|    See also PyThreadState_Get() and PyThreadState_GET(). */ | ||||
| static inline PyThreadState *_PyThreadState_GET(void) { | ||||
| static inline PyThreadState* | ||||
| _PyThreadState_GET(void) | ||||
| { | ||||
| #ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS | ||||
|     return _PyThreadState_GetTSS(); | ||||
| #else | ||||
|     return _PyRuntimeState_GetThreadState(&_PyRuntime); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| /* Redefine PyThreadState_GET() as an alias to _PyThreadState_GET() */ | ||||
|  |  | |||
|  | @ -380,9 +380,13 @@ PyEval_AcquireThread(PyThreadState *tstate) | |||
|     take_gil(tstate); | ||||
| 
 | ||||
|     struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; | ||||
| #ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS | ||||
|     (void)_PyThreadState_Swap(gilstate, tstate); | ||||
| #else | ||||
|     if (_PyThreadState_Swap(gilstate, tstate) != NULL) { | ||||
|         Py_FatalError("non-NULL old thread state"); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void | ||||
|  | @ -443,7 +447,12 @@ PyThreadState * | |||
| PyEval_SaveThread(void) | ||||
| { | ||||
|     _PyRuntimeState *runtime = &_PyRuntime; | ||||
| #ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS | ||||
|     PyThreadState *old_tstate = _PyThreadState_GET(); | ||||
|     PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, old_tstate); | ||||
| #else | ||||
|     PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); | ||||
| #endif | ||||
|     ensure_tstate_not_null(__func__, tstate); | ||||
| 
 | ||||
|     struct _ceval_runtime_state *ceval = &runtime->ceval; | ||||
|  | @ -866,9 +875,13 @@ eval_frame_handle_pending(PyThreadState *tstate) | |||
| 
 | ||||
|         take_gil(tstate); | ||||
| 
 | ||||
| #ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS | ||||
|         (void)_PyThreadState_Swap(&runtime->gilstate, tstate); | ||||
| #else | ||||
|         if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { | ||||
|             Py_FatalError("orphan tstate"); | ||||
|         } | ||||
| #endif | ||||
|     } | ||||
| 
 | ||||
|     /* Check for asynchronous exception. */ | ||||
|  |  | |||
|  | @ -956,6 +956,14 @@ _PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| #ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS | ||||
| PyThreadState* | ||||
| _PyThreadState_GetTSS(void) { | ||||
|     return PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| PyThreadState * | ||||
| _PyThreadState_UncheckedGet(void) | ||||
| { | ||||
|  | @ -975,7 +983,11 @@ PyThreadState_Get(void) | |||
| PyThreadState * | ||||
| _PyThreadState_Swap(struct _gilstate_runtime_state *gilstate, PyThreadState *newts) | ||||
| { | ||||
| #ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS | ||||
|     PyThreadState *oldts = _PyThreadState_GetTSS(); | ||||
| #else | ||||
|     PyThreadState *oldts = _PyRuntimeGILState_GetThreadState(gilstate); | ||||
| #endif | ||||
| 
 | ||||
|     _PyRuntimeGILState_SetThreadState(gilstate, newts); | ||||
|     /* It should not be possible for more than one thread state
 | ||||
|  | @ -993,6 +1005,9 @@ _PyThreadState_Swap(struct _gilstate_runtime_state *gilstate, PyThreadState *new | |||
|             Py_FatalError("Invalid thread state for this thread"); | ||||
|         errno = err; | ||||
|     } | ||||
| #endif | ||||
| #ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS | ||||
|     PyThread_tss_set(&gilstate->autoTSSkey, newts); | ||||
| #endif | ||||
|     return oldts; | ||||
| } | ||||
|  | @ -1363,7 +1378,9 @@ PyGILState_Ensure(void) | |||
| 
 | ||||
|     /* Ensure that _PyEval_InitThreads() and _PyGILState_Init() have been
 | ||||
|        called by Py_Initialize() */ | ||||
| #ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS | ||||
|     assert(_PyEval_ThreadsInitialized(runtime)); | ||||
| #endif | ||||
|     assert(gilstate->autoInterpreterState); | ||||
| 
 | ||||
|     PyThreadState *tcur = (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner