@@ -206,6 +206,26 @@ unbind_tstate(PyThreadState *tstate)
206
206
tstate -> native_thread_id = -1 ;
207
207
}
208
208
209
+ /* This is not exported, as it is not reliable! It can only
210
+ ever be compared to the state for the *current* thread.
211
+ * If not equal, then it doesn't matter that the actual
212
+ value may change immediately after comparison, as it can't
213
+ possibly change to the current thread's state.
214
+ * If equal, then the current thread holds the lock, so the value can't
215
+ change until we yield the lock.
216
+ */
217
+ static int
218
+ holds_gil (PyThreadState * tstate )
219
+ {
220
+ // XXX Fall back to tstate->interp->runtime->ceval.gil.last_holder
221
+ // (and tstate->interp->runtime->ceval.gil.locked).
222
+ assert (tstate != NULL );
223
+ _PyRuntimeState * runtime = tstate -> interp -> runtime ;
224
+ /* Must be the tstate for this thread */
225
+ assert (tstate == current_tss_get (runtime ));
226
+ return tstate == current_fast_get (runtime );
227
+ }
228
+
209
229
210
230
/* the global runtime */
211
231
@@ -1410,6 +1430,7 @@ _PyThreadState_Swap(_PyRuntimeState *runtime, PyThreadState *newts)
1410
1430
to be used for a thread. Check this the best we can in debug
1411
1431
builds.
1412
1432
*/
1433
+ // XXX The above isn't true when multiple interpreters are involved.
1413
1434
#if defined(Py_DEBUG )
1414
1435
if (newts && current_tss_initialized (runtime )) {
1415
1436
/* This can be called from PyEval_RestoreThread(). Similar
@@ -1692,24 +1713,6 @@ _PyThread_CurrentExceptions(void)
1692
1713
1693
1714
/* Python "auto thread state" API. */
1694
1715
1695
- /* Keep this as a static, as it is not reliable! It can only
1696
- ever be compared to the state for the *current* thread.
1697
- * If not equal, then it doesn't matter that the actual
1698
- value may change immediately after comparison, as it can't
1699
- possibly change to the current thread's state.
1700
- * If equal, then the current thread holds the lock, so the value can't
1701
- change until we yield the lock.
1702
- */
1703
- static int
1704
- PyThreadState_IsCurrent (PyThreadState * tstate )
1705
- {
1706
- assert (tstate != NULL );
1707
- _PyRuntimeState * runtime = tstate -> interp -> runtime ;
1708
- /* Must be the tstate for this thread */
1709
- assert (tstate == current_tss_get (runtime ));
1710
- return tstate == current_fast_get (runtime );
1711
- }
1712
-
1713
1716
/* Internal initialization/finalization functions called by
1714
1717
Py_Initialize/Py_FinalizeEx
1715
1718
*/
@@ -1817,7 +1820,7 @@ PyGILState_Ensure(void)
1817
1820
assert (runtime -> gilstate .autoInterpreterState != NULL );
1818
1821
1819
1822
PyThreadState * tcur = current_tss_get (runtime );
1820
- int current ;
1823
+ int has_gil ;
1821
1824
if (tcur == NULL ) {
1822
1825
/* Create a new Python thread state for this thread */
1823
1826
tcur = PyThreadState_New (runtime -> gilstate .autoInterpreterState );
@@ -1829,13 +1832,13 @@ PyGILState_Ensure(void)
1829
1832
matching call to PyGILState_Release(). */
1830
1833
assert (tcur -> gilstate_counter == 1 );
1831
1834
tcur -> gilstate_counter = 0 ;
1832
- current = 0 ; /* new thread state is never current */
1835
+ has_gil = 0 ; /* new thread state is never current */
1833
1836
}
1834
1837
else {
1835
- current = PyThreadState_IsCurrent (tcur );
1838
+ has_gil = holds_gil (tcur );
1836
1839
}
1837
1840
1838
- if (current == 0 ) {
1841
+ if (! has_gil ) {
1839
1842
PyEval_RestoreThread (tcur );
1840
1843
}
1841
1844
@@ -1846,7 +1849,7 @@ PyGILState_Ensure(void)
1846
1849
*/
1847
1850
++ tcur -> gilstate_counter ;
1848
1851
1849
- return current ? PyGILState_LOCKED : PyGILState_UNLOCKED ;
1852
+ return has_gil ? PyGILState_LOCKED : PyGILState_UNLOCKED ;
1850
1853
}
1851
1854
1852
1855
void
@@ -1864,12 +1867,12 @@ PyGILState_Release(PyGILState_STATE oldstate)
1864
1867
but while this is very new (April 2003), the extra check
1865
1868
by release-only users can't hurt.
1866
1869
*/
1867
- if (!PyThreadState_IsCurrent (tstate )) {
1870
+ if (!holds_gil (tstate )) {
1868
1871
_Py_FatalErrorFormat (__func__ ,
1869
1872
"thread state %p must be current when releasing" ,
1870
1873
tstate );
1871
1874
}
1872
- assert (PyThreadState_IsCurrent (tstate ));
1875
+ assert (holds_gil (tstate ));
1873
1876
-- tstate -> gilstate_counter ;
1874
1877
assert (tstate -> gilstate_counter >= 0 ); /* illegal counter value */
1875
1878
@@ -1889,8 +1892,9 @@ PyGILState_Release(PyGILState_STATE oldstate)
1889
1892
_PyThreadState_DeleteCurrent (tstate );
1890
1893
}
1891
1894
/* Release the lock if necessary */
1892
- else if (oldstate == PyGILState_UNLOCKED )
1895
+ else if (oldstate == PyGILState_UNLOCKED ) {
1893
1896
PyEval_SaveThread ();
1897
+ }
1894
1898
}
1895
1899
1896
1900
0 commit comments