Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2021-11-16 23:49:58 +0300
committerHans Goudey <h.goudey@me.com>2021-11-16 23:49:58 +0300
commit25d30e6c99a2d89bf7babfacb24a8c8aa61b3b3b (patch)
tree726c3c4aa4dbf1d9003e410832aa805356f32bb0
parentcfd0e96e47ed34888077b989854ba5a557bac43b (diff)
Fix T92857: Deadlock in geometry nodes curve multi-threading
The spline code, especially Bezier splines, often make use of lazily evaluation and caching. In order to do that, they use mutex locks. When multi-threading, this can lead to problems. Further detail can be found in rBfcc844f8fbd0d1. To fix the deadlock, isolate the task before multi-threading when holding a lock. Differential Revision: https://developer.blender.org/D13229
-rw-r--r--source/blender/blenkernel/intern/spline_bezier.cc16
1 files changed, 11 insertions, 5 deletions
diff --git a/source/blender/blenkernel/intern/spline_bezier.cc b/source/blender/blenkernel/intern/spline_bezier.cc
index 166fe0f5464..18d195f19da 100644
--- a/source/blender/blenkernel/intern/spline_bezier.cc
+++ b/source/blender/blenkernel/intern/spline_bezier.cc
@@ -599,7 +599,10 @@ Span<float> BezierSpline::evaluated_mappings() const
Span<int> offsets = this->control_point_offsets();
- calculate_mappings_linear_resolution(offsets, size, resolution_, is_cyclic_, mappings);
+ blender::threading::isolate_task([&]() {
+ /* Isolate the task, since this is function is multi-threaded and holds a lock. */
+ calculate_mappings_linear_resolution(offsets, size, resolution_, is_cyclic_, mappings);
+ });
mapping_cache_dirty_ = false;
return mappings;
@@ -635,10 +638,13 @@ Span<float3> BezierSpline::evaluated_positions() const
Span<int> offsets = this->control_point_offsets();
const int grain_size = std::max(512 / resolution_, 1);
- blender::threading::parallel_for(IndexRange(size - 1), grain_size, [&](IndexRange range) {
- for (const int i : range) {
- this->evaluate_segment(i, i + 1, positions.slice(offsets[i], offsets[i + 1] - offsets[i]));
- }
+ blender::threading::isolate_task([&]() {
+ /* Isolate the task, since this is function is multi-threaded and holds a lock. */
+ blender::threading::parallel_for(IndexRange(size - 1), grain_size, [&](IndexRange range) {
+ for (const int i : range) {
+ this->evaluate_segment(i, i + 1, positions.slice(offsets[i], offsets[i + 1] - offsets[i]));
+ }
+ });
});
if (is_cyclic_) {
this->evaluate_segment(