Fix T81688: BPY_thread_save crashes with Python 3.9

Calling PyEval_ReleaseLock() was crashing with Python 3.9
because it accessed the NULL pointer set by PyThreadState_Swap().

This happened when calling ViewLayer.update() for example.

While the existing logic could be fixed by swapping the thread-state
back before calling PyEval_ReleaseLock(), this depends on functions
which are tagged to be removed by v4.0.

Replace use of deprecated functions by calling PyEval_SaveThread(),
instead of inlining the logic, using _PyThreadState_UncheckedGet()
to prevent Python aborting.

The call to PyEval_ThreadsInitialized has been removed
as threads are now initialized with Python.
This could be replaced with Py_IsInitialized() however it doesn't look
like this is necessary.

This is compatible with Python 3.7 & 3.9.
This commit is contained in:
2020-10-14 18:36:04 +11:00
parent 2d4f1afece
commit 5edba9b42f

View File

@@ -29,14 +29,11 @@
/* analogue of PyEval_SaveThread() */
BPy_ThreadStatePtr BPY_thread_save(void)
{
PyThreadState *tstate = PyThreadState_Swap(NULL);
/* note: tstate can be NULL when quitting Blender */
if (tstate && PyEval_ThreadsInitialized()) {
PyEval_ReleaseLock();
/* The thread-state can be NULL when quitting Blender. */
if (_PyThreadState_UncheckedGet()) {
return (BPy_ThreadStatePtr)PyEval_SaveThread();
}
return (BPy_ThreadStatePtr)tstate;
return NULL;
}
/* analogue of PyEval_RestoreThread() */