mirror of
https://github.com/python/cpython.git
synced 2026-03-06 21:10:55 +00:00
When PyGILState_Ensure() is called in a non-Python thread before
PyEval_InitThreads(), only call PyEval_InitThreads() after calling
PyThreadState_New() to fix a crash.
Add an unit test in test_embed.
Enhance also embedded tests, backport from master:
* Add test_pre_initialization_api()
* Set PYTHONIOENCODING environment variable in
test_forced_io_encoding()
(cherry picked from commit b4d1e1f7c1)
This commit is contained in:
parent
29cb50ba34
commit
e10c9de9d7
4 changed files with 179 additions and 31 deletions
|
|
@ -865,6 +865,8 @@ PyGILState_Ensure(void)
|
|||
{
|
||||
int current;
|
||||
PyThreadState *tcur;
|
||||
int need_init_threads = 0;
|
||||
|
||||
/* Note that we do not auto-init Python here - apart from
|
||||
potential races with 2 threads auto-initializing, pep-311
|
||||
spells out other issues. Embedders are expected to have
|
||||
|
|
@ -873,10 +875,7 @@ PyGILState_Ensure(void)
|
|||
assert(autoInterpreterState); /* Py_Initialize() hasn't been called! */
|
||||
tcur = (PyThreadState *)PyThread_get_key_value(autoTLSkey);
|
||||
if (tcur == NULL) {
|
||||
/* At startup, Python has no concrete GIL. If PyGILState_Ensure() is
|
||||
called from a new thread for the first time, we need the create the
|
||||
GIL. */
|
||||
PyEval_InitThreads();
|
||||
need_init_threads = 1;
|
||||
|
||||
/* Create a new thread state for this thread */
|
||||
tcur = PyThreadState_New(autoInterpreterState);
|
||||
|
|
@ -887,16 +886,28 @@ PyGILState_Ensure(void)
|
|||
tcur->gilstate_counter = 0;
|
||||
current = 0; /* new thread state is never current */
|
||||
}
|
||||
else
|
||||
else {
|
||||
current = PyThreadState_IsCurrent(tcur);
|
||||
if (current == 0)
|
||||
}
|
||||
|
||||
if (current == 0) {
|
||||
PyEval_RestoreThread(tcur);
|
||||
}
|
||||
|
||||
/* Update our counter in the thread-state - no need for locks:
|
||||
- tcur will remain valid as we hold the GIL.
|
||||
- the counter is safe as we are the only thread "allowed"
|
||||
to modify this value
|
||||
*/
|
||||
++tcur->gilstate_counter;
|
||||
|
||||
if (need_init_threads) {
|
||||
/* At startup, Python has no concrete GIL. If PyGILState_Ensure() is
|
||||
called from a new thread for the first time, we need the create the
|
||||
GIL. */
|
||||
PyEval_InitThreads();
|
||||
}
|
||||
|
||||
return current ? PyGILState_LOCKED : PyGILState_UNLOCKED;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue