diff options
author | Sybren A. Stüvel <sybren@blender.org> | 2021-09-10 11:57:05 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@blender.org> | 2021-09-10 12:03:54 +0300 |
commit | fe4286435c54b3ba0a031f032b95615da74a7aac (patch) | |
tree | b118d6583176209e6a07c9781b484b622741abd3 /source/blender | |
parent | 93d2940603121acc47ea9860dac98e4e63c8f1d3 (diff) |
Depsgraph: release GIL when evaluating the depsgraph
Evaluating the dependency graph potentially executes Python code when
evaluating drivers. In specific situations (see T91046) this could
deadlock Blender entirely. Temporarily releasing the GIL when evaluating
the depsgraph resolves this.
This is an improved version of
rBfc460351170478e712740ae1917a2e24803eba3b, thanks @brecht for the diff!
Manifest task: T91046
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/depsgraph/CMakeLists.txt | 7 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/eval/deg_eval.cc | 13 | ||||
-rw-r--r-- | source/blender/python/generic/bpy_threads.c | 7 |
3 files changed, 23 insertions, 4 deletions
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt index 3ad26c6f4db..41253117096 100644 --- a/source/blender/depsgraph/CMakeLists.txt +++ b/source/blender/depsgraph/CMakeLists.txt @@ -161,6 +161,13 @@ set(LIB bf_blenkernel ) +if(WITH_PYTHON) + add_definitions(-DWITH_PYTHON) + list(APPEND INC + ../python + ) +endif() + blender_add_lib(bf_depsgraph "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") if(WITH_GTESTS) diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index ad88cf656ad..c816c7b8db5 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -41,6 +41,10 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" +#ifdef WITH_PYTHON +# include "BPY_extern.h" +#endif + #include "atomic_ops.h" #include "intern/depsgraph.h" @@ -375,6 +379,11 @@ void deg_evaluate_on_refresh(Depsgraph *graph) graph->debug.begin_graph_evaluation(); +#ifdef WITH_PYTHON + /* Release the GIL so that Python drivers can be evaluated. See T91046. */ + BPy_BEGIN_ALLOW_THREADS; +#endif + graph->is_evaluating = true; depsgraph_ensure_view_layer(graph); /* Set up evaluation state. */ @@ -415,6 +424,10 @@ void deg_evaluate_on_refresh(Depsgraph *graph) deg_graph_clear_tags(graph); graph->is_evaluating = false; +#ifdef WITH_PYTHON + BPy_END_ALLOW_THREADS; +#endif + graph->debug.end_graph_evaluation(); } diff --git a/source/blender/python/generic/bpy_threads.c b/source/blender/python/generic/bpy_threads.c index 57eb3a82c44..54548b88d4f 100644 --- a/source/blender/python/generic/bpy_threads.c +++ b/source/blender/python/generic/bpy_threads.c @@ -29,10 +29,9 @@ /* analogue of PyEval_SaveThread() */ BPy_ThreadStatePtr BPY_thread_save(void) { - /* Use `_PyThreadState_UncheckedGet()`, instead of more canonical `PyGILState_Check()` or - * `PyThreadState_Get()`, to avoid a fatal error issued when a thread state is NULL (the thread - * state can be NULL when quitting Blender). */ - if (_PyThreadState_UncheckedGet()) { + /* Don't use `PyThreadState_Get()`, to avoid a fatal error issued when a thread state is NULL + * (the thread state can be NULL when quitting Blender). */ + if (PyGILState_Check()) { return (BPy_ThreadStatePtr)PyEval_SaveThread(); } return NULL; |