From 5edba9b42f684bf8b99894bb6988e7f46180e12c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Oct 2020 18:36:04 +1100 Subject: 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. --- source/blender/python/generic/bpy_threads.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'source/blender/python') diff --git a/source/blender/python/generic/bpy_threads.c b/source/blender/python/generic/bpy_threads.c index 1aa36a0e685..bd707f728a1 100644 --- a/source/blender/python/generic/bpy_threads.c +++ b/source/blender/python/generic/bpy_threads.c @@ -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() */ -- cgit v1.2.3