mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	bpo-36710: Add runtime parameter to _PyThreadState_Init() (GH-12935)
* Add 'runtime' parameter to _PyThreadState_Init() * Add 'gilstate' parameter to _PyGILState_NoteThreadState() * Move _PyThreadState_Init() and _PyThreadState_DeleteExcept() to the internal C API.
This commit is contained in:
		
							parent
							
								
									6c44fde3e0
								
							
						
					
					
						commit
						8bb3230149
					
				
					 4 changed files with 95 additions and 82 deletions
				
			
		|  | @ -155,8 +155,6 @@ PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_Get(void); | ||||||
| PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*); | PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*); | ||||||
| PyAPI_FUNC(void) _PyState_ClearModules(void); | PyAPI_FUNC(void) _PyState_ClearModules(void); | ||||||
| PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *); | PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *); | ||||||
| PyAPI_FUNC(void) _PyThreadState_Init(PyThreadState *); |  | ||||||
| PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate); |  | ||||||
| PyAPI_FUNC(void) _PyGILState_Reinit(void); | PyAPI_FUNC(void) _PyGILState_Reinit(void); | ||||||
| 
 | 
 | ||||||
| /* Similar to PyThreadState_Get(), but don't issue a fatal error
 | /* Similar to PyThreadState_Get(), but don't issue a fatal error
 | ||||||
|  |  | ||||||
|  | @ -231,6 +231,11 @@ PyAPI_FUNC(void) _PyRuntime_Finalize(void); | ||||||
| 
 | 
 | ||||||
| /* Other */ | /* Other */ | ||||||
| 
 | 
 | ||||||
|  | PyAPI_FUNC(void) _PyThreadState_Init( | ||||||
|  |     _PyRuntimeState *runtime, | ||||||
|  |     PyThreadState *tstate); | ||||||
|  | PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate); | ||||||
|  | 
 | ||||||
| PyAPI_FUNC(_PyInitError) _PyInterpreterState_Enable(_PyRuntimeState *); | PyAPI_FUNC(_PyInitError) _PyInterpreterState_Enable(_PyRuntimeState *); | ||||||
| PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(void); | PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(void); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -994,7 +994,7 @@ t_bootstrap(void *boot_raw) | ||||||
| 
 | 
 | ||||||
|     tstate = boot->tstate; |     tstate = boot->tstate; | ||||||
|     tstate->thread_id = PyThread_get_thread_ident(); |     tstate->thread_id = PyThread_get_thread_ident(); | ||||||
|     _PyThreadState_Init(tstate); |     _PyThreadState_Init(&_PyRuntime, tstate); | ||||||
|     PyEval_AcquireThread(tstate); |     PyEval_AcquireThread(tstate); | ||||||
|     tstate->interp->num_threads++; |     tstate->interp->num_threads++; | ||||||
|     res = PyObject_Call(boot->func, boot->args, boot->keyw); |     res = PyObject_Call(boot->func, boot->args, boot->keyw); | ||||||
|  |  | ||||||
|  | @ -133,7 +133,9 @@ _PyRuntimeState_ReInitThreads(void) | ||||||
|                                           WAIT_LOCK) |                                           WAIT_LOCK) | ||||||
| #define HEAD_UNLOCK() PyThread_release_lock(_PyRuntime.interpreters.mutex) | #define HEAD_UNLOCK() PyThread_release_lock(_PyRuntime.interpreters.mutex) | ||||||
| 
 | 
 | ||||||
| static void _PyGILState_NoteThreadState(PyThreadState* tstate); | /* Forward declaration */ | ||||||
|  | static void _PyGILState_NoteThreadState( | ||||||
|  |     struct _gilstate_runtime_state *gilstate, PyThreadState* tstate); | ||||||
| 
 | 
 | ||||||
| _PyInitError | _PyInitError | ||||||
| _PyInterpreterState_Enable(_PyRuntimeState *runtime) | _PyInterpreterState_Enable(_PyRuntimeState *runtime) | ||||||
|  | @ -487,11 +489,14 @@ static PyThreadState * | ||||||
| new_threadstate(PyInterpreterState *interp, int init) | new_threadstate(PyInterpreterState *interp, int init) | ||||||
| { | { | ||||||
|     PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState)); |     PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState)); | ||||||
|  |     if (tstate == NULL) { | ||||||
|  |         return NULL; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     if (_PyThreadState_GetFrame == NULL) |     if (_PyThreadState_GetFrame == NULL) { | ||||||
|         _PyThreadState_GetFrame = threadstate_getframe; |         _PyThreadState_GetFrame = threadstate_getframe; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     if (tstate != NULL) { |  | ||||||
|     tstate->interp = interp; |     tstate->interp = interp; | ||||||
| 
 | 
 | ||||||
|     tstate->frame = NULL; |     tstate->frame = NULL; | ||||||
|  | @ -540,8 +545,9 @@ new_threadstate(PyInterpreterState *interp, int init) | ||||||
| 
 | 
 | ||||||
|     tstate->id = ++interp->tstate_next_unique_id; |     tstate->id = ++interp->tstate_next_unique_id; | ||||||
| 
 | 
 | ||||||
|         if (init) |     if (init) { | ||||||
|             _PyThreadState_Init(tstate); |         _PyThreadState_Init(&_PyRuntime, tstate); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     HEAD_LOCK(); |     HEAD_LOCK(); | ||||||
|     tstate->prev = NULL; |     tstate->prev = NULL; | ||||||
|  | @ -550,7 +556,6 @@ new_threadstate(PyInterpreterState *interp, int init) | ||||||
|         tstate->next->prev = tstate; |         tstate->next->prev = tstate; | ||||||
|     interp->tstate_head = tstate; |     interp->tstate_head = tstate; | ||||||
|     HEAD_UNLOCK(); |     HEAD_UNLOCK(); | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     return tstate; |     return tstate; | ||||||
| } | } | ||||||
|  | @ -568,9 +573,9 @@ _PyThreadState_Prealloc(PyInterpreterState *interp) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| _PyThreadState_Init(PyThreadState *tstate) | _PyThreadState_Init(_PyRuntimeState *runtime, PyThreadState *tstate) | ||||||
| { | { | ||||||
|     _PyGILState_NoteThreadState(tstate); |     _PyGILState_NoteThreadState(&runtime->gilstate, tstate); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PyObject* | PyObject* | ||||||
|  | @ -1037,17 +1042,23 @@ PyThreadState_IsCurrent(PyThreadState *tstate) | ||||||
|    Py_Initialize/Py_FinalizeEx |    Py_Initialize/Py_FinalizeEx | ||||||
| */ | */ | ||||||
| void | void | ||||||
| _PyGILState_Init(PyInterpreterState *i, PyThreadState *t) | _PyGILState_Init(PyInterpreterState *interp, PyThreadState *tstate) | ||||||
| { | { | ||||||
|     assert(i && t); /* must init with valid states */ |     /* must init with valid states */ | ||||||
|     if (PyThread_tss_create(&_PyRuntime.gilstate.autoTSSkey) != 0) { |     assert(interp != NULL); | ||||||
|  |     assert(tstate != NULL); | ||||||
|  | 
 | ||||||
|  |     _PyRuntimeState *runtime = &_PyRuntime; | ||||||
|  |     struct _gilstate_runtime_state *gilstate = &runtime->gilstate; | ||||||
|  | 
 | ||||||
|  |     if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) { | ||||||
|         Py_FatalError("Could not allocate TSS entry"); |         Py_FatalError("Could not allocate TSS entry"); | ||||||
|     } |     } | ||||||
|     _PyRuntime.gilstate.autoInterpreterState = i; |     gilstate->autoInterpreterState = interp; | ||||||
|     assert(PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey) == NULL); |     assert(PyThread_tss_get(&gilstate->autoTSSkey) == NULL); | ||||||
|     assert(t->gilstate_counter == 0); |     assert(tstate->gilstate_counter == 0); | ||||||
| 
 | 
 | ||||||
|     _PyGILState_NoteThreadState(t); |     _PyGILState_NoteThreadState(gilstate, tstate); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PyInterpreterState * | PyInterpreterState * | ||||||
|  | @ -1104,13 +1115,14 @@ _PyGILState_Reinit(void) | ||||||
|    a better fix for SF bug #1010677 than the first one attempted). |    a better fix for SF bug #1010677 than the first one attempted). | ||||||
| */ | */ | ||||||
| static void | static void | ||||||
| _PyGILState_NoteThreadState(PyThreadState* tstate) | _PyGILState_NoteThreadState(struct _gilstate_runtime_state *gilstate, PyThreadState* tstate) | ||||||
| { | { | ||||||
|     /* If autoTSSkey isn't initialized, this must be the very first
 |     /* If autoTSSkey isn't initialized, this must be the very first
 | ||||||
|        threadstate created in Py_Initialize().  Don't do anything for now |        threadstate created in Py_Initialize().  Don't do anything for now | ||||||
|        (we'll be back here when _PyGILState_Init is called). */ |        (we'll be back here when _PyGILState_Init is called). */ | ||||||
|     if (!_PyRuntime.gilstate.autoInterpreterState) |     if (!gilstate->autoInterpreterState) { | ||||||
|         return; |         return; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     /* Stick the thread state for this thread in thread specific storage.
 |     /* Stick the thread state for this thread in thread specific storage.
 | ||||||
| 
 | 
 | ||||||
|  | @ -1124,10 +1136,8 @@ _PyGILState_NoteThreadState(PyThreadState* tstate) | ||||||
|        The first thread state created for that given OS level thread will |        The first thread state created for that given OS level thread will | ||||||
|        "win", which seems reasonable behaviour. |        "win", which seems reasonable behaviour. | ||||||
|     */ |     */ | ||||||
|     if (PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey) == NULL) { |     if (PyThread_tss_get(&gilstate->autoTSSkey) == NULL) { | ||||||
|         if ((PyThread_tss_set(&_PyRuntime.gilstate.autoTSSkey, (void *)tstate) |         if ((PyThread_tss_set(&gilstate->autoTSSkey, (void *)tstate)) != 0) { | ||||||
|              ) != 0) |  | ||||||
|         { |  | ||||||
|             Py_FatalError("Couldn't create autoTSSkey mapping"); |             Py_FatalError("Couldn't create autoTSSkey mapping"); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner