| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent d7fabc1 commit 23ef89d
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -57,6 +57,8 @@ extern PyObject *_PyEval_EvalCode( | |||
| 57 | 57 | extern int _PyEval_ThreadsInitialized(_PyRuntimeState *runtime); | |
| 58 | 58 | extern PyStatus _PyEval_InitThreads(PyThreadState *tstate); | |
| 59 | 59 | ||
| 60 | + extern void _PyEval_ReleaseLock(PyThreadState *tstate); | ||
| 61 | + | ||
| 60 | 62 | ||
| 61 | 63 | /* --- _Py_EnterRecursiveCall() ----------------------------------------- */ | |
| 62 | 64 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -104,7 +104,7 @@ PyAPI_FUNC(void) _PyErr_Print(PyThreadState *tstate); | |||
| 104 | 104 | PyAPI_FUNC(void) _PyErr_Display(PyObject *file, PyObject *exception, | |
| 105 | 105 | PyObject *value, PyObject *tb); | |
| 106 | 106 | ||
| 107 | - PyAPI_FUNC(void) _PyThreadState_DeleteCurrent(struct pyruntimestate *runtime); | ||
| 107 | + PyAPI_FUNC(void) _PyThreadState_DeleteCurrent(PyThreadState *tstate); | ||
| 108 | 108 | ||
| 109 | 109 | #ifdef __cplusplus | |
| 110 | 110 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -62,7 +62,8 @@ def test_no_FatalError_infinite_loop(self): | |||
| 62 | 62 | # This used to cause an infinite loop. | |
| 63 | 63 | self.assertTrue(err.rstrip().startswith( | |
| 64 | 64 | b'Fatal Python error: ' | |
| 65 | - b'PyThreadState_Get: no current thread')) | ||
| 65 | + b'PyThreadState_Get: ' | ||
| 66 | + b'current thread state is NULL (released GIL?)')) | ||
| 66 | 67 | ||
| 67 | 68 | def test_memoryview_from_NULL_pointer(self): | |
| 68 | 69 | self.assertRaises(ValueError, _testcapi.make_memoryview_from_NULL_pointer) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1028,7 +1028,7 @@ t_bootstrap(void *boot_raw) | |||
| 1028 | 1028 | PyMem_DEL(boot_raw); | |
| 1029 | 1029 | tstate->interp->num_threads--; | |
| 1030 | 1030 | PyThreadState_Clear(tstate); | |
| 1031 | - _PyThreadState_DeleteCurrent(runtime); | ||
| 1031 | + _PyThreadState_DeleteCurrent(tstate); | ||
| 1032 | 1032 | PyThread_exit_thread(); | |
| 1033 | 1033 | } | |
| 1034 | 1034 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -193,7 +193,8 @@ static void | |||
| 193 | 193 | ensure_tstate_not_null(const char *func, PyThreadState *tstate) | |
| 194 | 194 | { | |
| 195 | 195 | if (tstate == NULL) { | |
| 196 | - _Py_FatalErrorFunc(func, "current thread state is NULL"); | ||
| 196 | + _Py_FatalErrorFunc(func, | ||
| 197 | + "current thread state is NULL (released GIL?)"); | ||
| 197 | 198 | } | |
| 198 | 199 | } | |
| 199 | 200 | ||
@@ -313,6 +314,13 @@ PyEval_ReleaseLock(void) | |||
| 313 | 314 | drop_gil(&runtime->ceval, tstate); | |
| 314 | 315 | } | |
| 315 | 316 | ||
| 317 | + void | ||
| 318 | + _PyEval_ReleaseLock(PyThreadState *tstate) | ||
| 319 | + { | ||
| 320 | + struct _ceval_runtime_state *ceval = &tstate->interp->runtime->ceval; | ||
| 321 | + drop_gil(ceval, tstate); | ||
| 322 | + } | ||
| 323 | + | ||
| 316 | 324 | void | |
| 317 | 325 | PyEval_AcquireThread(PyThreadState *tstate) | |
| 318 | 326 | { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -37,6 +37,16 @@ extern "C" { | |||
| 37 | 37 | _Py_atomic_store_relaxed(&(gilstate)->tstate_current, \ | |
| 38 | 38 | (uintptr_t)(value)) | |
| 39 | 39 | ||
| 40 | + static void | ||
| 41 | + ensure_tstate_not_null(const char *func, PyThreadState *tstate) | ||
| 42 | + { | ||
| 43 | + if (tstate == NULL) { | ||
| 44 | + _Py_FatalErrorFunc(func, | ||
| 45 | + "current thread state is NULL (released GIL?)"); | ||
| 46 | + } | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + | ||
| 40 | 50 | /* Forward declarations */ | |
| 41 | 51 | static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate); | |
| 42 | 52 | static void _PyThreadState_Delete(PyThreadState *tstate, int check_current); | |
@@ -400,9 +410,7 @@ PyInterpreterState * | |||
| 400 | 410 | PyInterpreterState_Get(void) | |
| 401 | 411 | { | |
| 402 | 412 | PyThreadState *tstate = _PyThreadState_GET(); | |
| 403 | - if (tstate == NULL) { | ||
| 404 | - Py_FatalError("no current thread state"); | ||
| 405 | - } | ||
| 413 | + ensure_tstate_not_null(__func__, tstate); | ||
| 406 | 414 | PyInterpreterState *interp = tstate->interp; | |
| 407 | 415 | if (interp == NULL) { | |
| 408 | 416 | Py_FatalError("no current interpreter"); | |
@@ -819,9 +827,7 @@ tstate_delete_common(PyThreadState *tstate, | |||
| 819 | 827 | struct _gilstate_runtime_state *gilstate) | |
| 820 | 828 | { | |
| 821 | 829 | _PyRuntimeState *runtime = tstate->interp->runtime; | |
| 822 | - if (tstate == NULL) { | ||
| 823 | - Py_FatalError("NULL tstate"); | ||
| 824 | - } | ||
| 830 | + ensure_tstate_not_null(__func__, tstate); | ||
| 825 | 831 | PyInterpreterState *interp = tstate->interp; | |
| 826 | 832 | if (interp == NULL) { | |
| 827 | 833 | Py_FatalError("NULL interp"); | |
@@ -835,8 +841,6 @@ tstate_delete_common(PyThreadState *tstate, | |||
| 835 | 841 | tstate->next->prev = tstate->prev; | |
| 836 | 842 | HEAD_UNLOCK(runtime); | |
| 837 | 843 | ||
| 838 | - PyMem_RawFree(tstate); | ||
| 839 | - | ||
| 840 | 844 | if (gilstate->autoInterpreterState && | |
| 841 | 845 | PyThread_tss_get(&gilstate->autoTSSkey) == tstate) | |
| 842 | 846 | { | |
@@ -855,6 +859,7 @@ _PyThreadState_Delete(PyThreadState *tstate, int check_current) | |||
| 855 | 859 | } | |
| 856 | 860 | } | |
| 857 | 861 | tstate_delete_common(tstate, gilstate); | |
| 862 | + PyMem_RawFree(tstate); | ||
| 858 | 863 | } | |
| 859 | 864 | ||
| 860 | 865 | ||
@@ -866,22 +871,22 @@ PyThreadState_Delete(PyThreadState *tstate) | |||
| 866 | 871 | ||
| 867 | 872 | ||
| 868 | 873 | void | |
| 869 | - _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime) | ||
| 874 | + _PyThreadState_DeleteCurrent(PyThreadState *tstate) | ||
| 870 | 875 | { | |
| 871 | - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; | ||
| 872 | - PyThreadState *tstate = _PyRuntimeGILState_GetThreadState(gilstate); | ||
| 873 | - if (tstate == NULL) { | ||
| 874 | - Py_FatalError("no current tstate"); | ||
| 875 | - } | ||
| 876 | + ensure_tstate_not_null(__func__, tstate); | ||
| 877 | + struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; | ||
| 876 | 878 | tstate_delete_common(tstate, gilstate); | |
| 877 | 879 | _PyRuntimeGILState_SetThreadState(gilstate, NULL); | |
| 878 | - PyEval_ReleaseLock(); | ||
| 880 | + _PyEval_ReleaseLock(tstate); | ||
| 881 | + PyMem_RawFree(tstate); | ||
| 879 | 882 | } | |
| 880 | 883 | ||
| 881 | 884 | void | |
| 882 | 885 | PyThreadState_DeleteCurrent(void) | |
| 883 | 886 | { | |
| 884 | - _PyThreadState_DeleteCurrent(&_PyRuntime); | ||
| 887 | + struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; | ||
| 888 | + PyThreadState *tstate = _PyRuntimeGILState_GetThreadState(gilstate); | ||
| 889 | + _PyThreadState_DeleteCurrent(tstate); | ||
| 885 | 890 | } | |
| 886 | 891 | ||
| 887 | 892 | ||
@@ -938,9 +943,7 @@ PyThreadState * | |||
| 938 | 943 | PyThreadState_Get(void) | |
| 939 | 944 | { | |
| 940 | 945 | PyThreadState *tstate = _PyThreadState_GET(); | |
| 941 | - if (tstate == NULL) { | ||
| 942 | - Py_FatalError("no current thread"); | ||
| 943 | - } | ||
| 946 | + ensure_tstate_not_null(__func__, tstate); | ||
| 944 | 947 | return tstate; | |
| 945 | 948 | } | |
| 946 | 949 | ||
@@ -1342,8 +1345,8 @@ void | |||
| 1342 | 1345 | PyGILState_Release(PyGILState_STATE oldstate) | |
| 1343 | 1346 | { | |
| 1344 | 1347 | _PyRuntimeState *runtime = &_PyRuntime; | |
| 1345 | - PyThreadState *tcur = PyThread_tss_get(&runtime->gilstate.autoTSSkey); | ||
| 1346 | - if (tcur == NULL) { | ||
| 1348 | + PyThreadState *tstate = PyThread_tss_get(&runtime->gilstate.autoTSSkey); | ||
| 1349 | + if (tstate == NULL) { | ||
| 1347 | 1350 | Py_FatalError("auto-releasing thread-state, " | |
| 1348 | 1351 | "but no thread-state for this thread"); | |
| 1349 | 1352 | } | |
@@ -1353,26 +1356,27 @@ PyGILState_Release(PyGILState_STATE oldstate) | |||
| 1353 | 1356 | but while this is very new (April 2003), the extra check | |
| 1354 | 1357 | by release-only users can't hurt. | |
| 1355 | 1358 | */ | |
| 1356 | - if (!PyThreadState_IsCurrent(tcur)) { | ||
| 1359 | + if (!PyThreadState_IsCurrent(tstate)) { | ||
| 1357 | 1360 | Py_FatalError("This thread state must be current when releasing"); | |
| 1358 | 1361 | } | |
| 1359 | - assert(PyThreadState_IsCurrent(tcur)); | ||
| 1360 | - --tcur->gilstate_counter; | ||
| 1361 | - assert(tcur->gilstate_counter >= 0); /* illegal counter value */ | ||
| 1362 | + assert(PyThreadState_IsCurrent(tstate)); | ||
| 1363 | + --tstate->gilstate_counter; | ||
| 1364 | + assert(tstate->gilstate_counter >= 0); /* illegal counter value */ | ||
| 1362 | 1365 | ||
| 1363 | 1366 | /* If we're going to destroy this thread-state, we must | |
| 1364 | 1367 | * clear it while the GIL is held, as destructors may run. | |
| 1365 | 1368 | */ | |
| 1366 | - if (tcur->gilstate_counter == 0) { | ||
| 1369 | + if (tstate->gilstate_counter == 0) { | ||
| 1367 | 1370 | /* can't have been locked when we created it */ | |
| 1368 | 1371 | assert(oldstate == PyGILState_UNLOCKED); | |
| 1369 | - PyThreadState_Clear(tcur); | ||
| 1372 | + PyThreadState_Clear(tstate); | ||
| 1370 | 1373 | /* Delete the thread-state. Note this releases the GIL too! | |
| 1371 | 1374 | * It's vital that the GIL be held here, to avoid shutdown | |
| 1372 | 1375 | * races; see bugs 225673 and 1061968 (that nasty bug has a | |
| 1373 | 1376 | * habit of coming back). | |
| 1374 | 1377 | */ | |
| 1375 | - _PyThreadState_DeleteCurrent(runtime); | ||
| 1378 | + assert(_PyRuntimeGILState_GetThreadState(&runtime->gilstate) == tstate); | ||
| 1379 | + _PyThreadState_DeleteCurrent(tstate); | ||
| 1376 | 1380 | } | |
| 1377 | 1381 | /* Release the lock if necessary */ | |
| 1378 | 1382 | else if (oldstate == PyGILState_UNLOCKED) | |
| Back | FazBrowse Home | New Git URL |
0 commit comments