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:
authorSergey Sharybin <sergey.vfx@gmail.com>2014-01-23 14:24:41 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2014-01-23 14:30:57 +0400
commitcbdedc169dd948d308dcdb1fc2e74b1fdd25880c (patch)
treee16c55249715cef6136b4605b4bb165356e0046e /source/blender/blenkernel/intern/customdata.c
parent6c1c6f22cea9729c40e02ed45374bad31fbca6dd (diff)
Fix T38284: Crash with several shrinkwrap constraint using same target
Issue is caused by the race condition between getting custom data layers from target's derived mesh (for vertices and faces) and releasing this derived mesh from other threads. When one releases the derived mesh it'll free temporary data from it, and it'll also update data layers mapping. General rule for threading is that no one is ever allowed to modify data he doesn't own. This means that no temp layers are to be allocated in derived mesh and making it so `CustomData_free_temporary()` doesn't update mapping if nothing was freed will solve the race condition. It is still possible to do other improvements, namely detect which additional data/layers are to be present in derived mesh and create it as a part of `object_handle_update()`, but this is to be solved separately.
Diffstat (limited to 'source/blender/blenkernel/intern/customdata.c')
-rw-r--r--source/blender/blenkernel/intern/customdata.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index ccb167ab6a9..fc123d37a7b 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -1914,6 +1914,7 @@ void CustomData_free_temporary(CustomData *data, int totelem)
{
CustomDataLayer *layer;
int i, j;
+ bool changed = false;
for (i = 0, j = 0; i < data->totlayer; ++i) {
layer = &data->layers[i];
@@ -1921,18 +1922,24 @@ void CustomData_free_temporary(CustomData *data, int totelem)
if (i != j)
data->layers[j] = data->layers[i];
- if ((layer->flag & CD_FLAG_TEMPORARY) == CD_FLAG_TEMPORARY)
+ if ((layer->flag & CD_FLAG_TEMPORARY) == CD_FLAG_TEMPORARY) {
customData_free_layer__internal(layer, totelem);
+ changed = true;
+ }
else
j++;
}
data->totlayer = j;
- if (data->totlayer <= data->maxlayer - CUSTOMDATA_GROW)
+ if (data->totlayer <= data->maxlayer - CUSTOMDATA_GROW) {
customData_resize(data, -CUSTOMDATA_GROW);
+ changed = true;
+ }
- customData_update_offsets(data);
+ if (changed) {
+ customData_update_offsets(data);
+ }
}
void CustomData_set_only_copy(const struct CustomData *data,