Skip to content

Commit

Permalink
gh-59956: Add a Test to Verify GILState Matches the "Current" Thread …
Browse files Browse the repository at this point in the history
…State (gh-101625)

This test should have been in gh-101431.

#59956
  • Loading branch information
ericsnowcurrently authored Feb 6, 2023
1 parent 3875276 commit 914f8fd
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Lib/test/test_capi/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,9 @@ def callback():
ret = assert_python_ok('-X', 'tracemalloc', '-c', code)
self.assertIn(b'callback called', ret.out)

def test_gilstate_matches_current(self):
_testcapi.test_current_tstate_matches()


class Test_testcapi(unittest.TestCase):
locals().update((name, getattr(_testcapi, name))
Expand Down
37 changes: 37 additions & 0 deletions Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1534,6 +1534,42 @@ crash_no_current_thread(PyObject *self, PyObject *Py_UNUSED(ignored))
return NULL;
}

/* Test that the GILState thread and the "current" thread match. */
static PyObject *
test_current_tstate_matches(PyObject *self, PyObject *Py_UNUSED(ignored))
{
PyThreadState *orig_tstate = PyThreadState_Get();

if (orig_tstate != PyGILState_GetThisThreadState()) {
PyErr_SetString(PyExc_RuntimeError,
"current thread state doesn't match GILState");
return NULL;
}

const char *err = NULL;
PyThreadState_Swap(NULL);
PyThreadState *substate = Py_NewInterpreter();

if (substate != PyThreadState_Get()) {
err = "subinterpreter thread state not current";
goto finally;
}
if (substate != PyGILState_GetThisThreadState()) {
err = "subinterpreter thread state doesn't match GILState";
goto finally;
}

finally:
Py_EndInterpreter(substate);
PyThreadState_Swap(orig_tstate);

if (err != NULL) {
PyErr_SetString(PyExc_RuntimeError, err);
return NULL;
}
Py_RETURN_NONE;
}

/* To run some code in a sub-interpreter. */
static PyObject *
run_in_subinterp(PyObject *self, PyObject *args)
Expand Down Expand Up @@ -3354,6 +3390,7 @@ static PyMethodDef TestMethods[] = {
{"make_memoryview_from_NULL_pointer", make_memoryview_from_NULL_pointer,
METH_NOARGS},
{"crash_no_current_thread", crash_no_current_thread, METH_NOARGS},
{"test_current_tstate_matches", test_current_tstate_matches, METH_NOARGS},
{"run_in_subinterp", run_in_subinterp, METH_VARARGS},
{"run_in_subinterp_with_config",
_PyCFunction_CAST(run_in_subinterp_with_config),
Expand Down

0 comments on commit 914f8fd

Please sign in to comment.