diff options
author | Evangelos Trantos <evtrados@gmail.com> | 2022-04-20 14:34:27 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-20 14:34:27 +0300 |
commit | 512caf35ba1ef7b0c35021443691ab2fe4a1d640 (patch) | |
tree | a92a41635b1a5f6c3439f4aa01208ed3a1762a46 | |
parent | d52b9c4fe0888334252dc8cdcbb4d15208abf893 (diff) | |
parent | 550d807b383104c29776f609fbe55df5ac915142 (diff) |
Merge pull request #1645 from Ultimaker/CURA-9159_fix_threaded_tree_crash
[CURA-9159] Fix occasional crash due to unsafe threading in tree support.
-rw-r--r-- | src/TreeModelVolumes.cpp | 7 | ||||
-rw-r--r-- | src/TreeModelVolumes.h | 8 | ||||
-rw-r--r-- | src/TreeSupport.cpp | 5 |
3 files changed, 15 insertions, 5 deletions
diff --git a/src/TreeModelVolumes.cpp b/src/TreeModelVolumes.cpp index 7479d5a82..1c6889ee8 100644 --- a/src/TreeModelVolumes.cpp +++ b/src/TreeModelVolumes.cpp @@ -104,6 +104,8 @@ const Polygons& TreeModelVolumes::calculateCollision(const RadiusLayerPair& key) collision_areas = collision_areas.unionPolygons(collision_model.offset(radius)); } } + + const std::lock_guard<std::mutex> lock(object_mutex_); const auto ret = collision_cache_.insert({key, std::move(collision_areas)}); assert(ret.second); return ret.first->second; @@ -135,6 +137,8 @@ const Polygons& TreeModelVolumes::calculateAvoidance(const RadiusLayerPair& key) } auto avoidance_areas = getAvoidance(radius, layer_idx - 1).offset(-max_move_).smooth(5); avoidance_areas = avoidance_areas.unionPolygons(getCollision(radius, layer_idx)); + + const std::lock_guard<std::mutex> lock(object_mutex_); const auto ret = avoidance_cache_.insert({key, std::move(avoidance_areas)}); assert(ret.second); return ret.first->second; @@ -144,8 +148,9 @@ const Polygons& TreeModelVolumes::calculateInternalModel(const RadiusLayerPair& { const auto& radius = key.first; const auto& layer_idx = key.second; - const auto& internal_areas = getAvoidance(radius, layer_idx).difference(getCollision(radius, layer_idx)); + + const std::lock_guard<std::mutex> lock(object_mutex_); const auto ret = internal_model_cache_.insert({key, internal_areas}); assert(ret.second); return ret.first->second; diff --git a/src/TreeModelVolumes.h b/src/TreeModelVolumes.h index 74f2b4cc3..29d23b0d6 100644 --- a/src/TreeModelVolumes.h +++ b/src/TreeModelVolumes.h @@ -4,6 +4,7 @@ #ifndef TREEMODELVOLUMES_H #define TREEMODELVOLUMES_H +#include <mutex> #include <unordered_map> #include "settings/EnumSettings.h" //To store whether X/Y or Z distance gets priority. @@ -20,7 +21,7 @@ class Settings; /*! * \brief Lazily generates tree guidance volumes. * - * \warning This class is not currently thread-safe and should not be accessed in OpenMP blocks + * \warning This class blocks on thread access. Use calls to this in threaded blocks sparingly. */ class TreeModelVolumes { @@ -195,6 +196,11 @@ private: mutable std::unordered_map<RadiusLayerPair, Polygons> collision_cache_; mutable std::unordered_map<RadiusLayerPair, Polygons> avoidance_cache_; mutable std::unordered_map<RadiusLayerPair, Polygons> internal_model_cache_; + + /*! + * \brief Used to make the class thread-safe. + */ + mutable std::mutex object_mutex_; }; } diff --git a/src/TreeSupport.cpp b/src/TreeSupport.cpp index 6edfa7f29..278cd3e16 100644 --- a/src/TreeSupport.cpp +++ b/src/TreeSupport.cpp @@ -31,10 +31,9 @@ namespace cura { -TreeSupport::TreeSupport(const SliceDataStorage& storage) +TreeSupport::TreeSupport(const SliceDataStorage& storage) : + volumes_(storage, Application::getInstance().current_slice->scene.current_mesh_group->settings) { - const Settings& mesh_group_settings = Application::getInstance().current_slice->scene.current_mesh_group->settings; - volumes_ = TreeModelVolumes(storage, mesh_group_settings); } void TreeSupport::generateSupportAreas(SliceDataStorage& storage) |