diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2013-04-26 12:30:55 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2013-04-26 12:30:55 +0400 |
commit | 708622c7f20e206ab18ffb56db8b78c319916eda (patch) | |
tree | 75be75b05232bf8403e26d62202f5bb5bc515e9e /source/blender/blenkernel/intern | |
parent | e77729f5ddd5f2c64cf1aeda08a8ccce63b2ec62 (diff) |
Fix #35082: Blender Freeze when change smoke domain setting
Issue was introduced by svn rev56273 and was caused by
both smokeModifier_do and smokeModifier_reset (which is
called from smokeModifier_do) do mutex lock/unlock.
This lead to quite undefined behavior caused by the same
thread released mutex twice.
Solved by not locking mutex from inside routines calling
from smokeModifier_process -- mutex is locked in parent
function anyway.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/smoke.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index f31a672c664..b61cd63f503 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -428,7 +428,7 @@ void smokeModifier_reset_turbulence(struct SmokeModifierData *smd) } } -void smokeModifier_reset(struct SmokeModifierData *smd) +static void smokeModifier_reset_ex(struct SmokeModifierData *smd, bool need_lock) { if (smd) { @@ -440,12 +440,14 @@ void smokeModifier_reset(struct SmokeModifierData *smd) if (smd->domain->fluid) { - BLI_rw_mutex_lock(smd->domain->fluid_mutex, THREAD_LOCK_WRITE); + if (need_lock) + BLI_rw_mutex_lock(smd->domain->fluid_mutex, THREAD_LOCK_WRITE); smoke_free(smd->domain->fluid); smd->domain->fluid = NULL; - BLI_rw_mutex_unlock(smd->domain->fluid_mutex); + if (need_lock) + BLI_rw_mutex_unlock(smd->domain->fluid_mutex); } smokeModifier_reset_turbulence(smd); @@ -473,6 +475,11 @@ void smokeModifier_reset(struct SmokeModifierData *smd) } } +void smokeModifier_reset(struct SmokeModifierData *smd) +{ + smokeModifier_reset_ex(smd, true); +} + void smokeModifier_free(SmokeModifierData *smd) { if (smd) @@ -2194,7 +2201,7 @@ static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object * else if (scene->r.cfra < smd->time) { smd->time = scene->r.cfra; - smokeModifier_reset(smd); + smokeModifier_reset_ex(smd, false); } } else if (smd->type & MOD_SMOKE_TYPE_COLL) @@ -2214,7 +2221,7 @@ static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object * smd->time = scene->r.cfra; if (scene->r.cfra < smd->time) { - smokeModifier_reset(smd); + smokeModifier_reset_ex(smd, false); } } else if (smd->type & MOD_SMOKE_TYPE_DOMAIN) @@ -2236,7 +2243,7 @@ static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object * if (!smd->domain->fluid || framenr == startframe) { BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); - smokeModifier_reset(smd); + smokeModifier_reset_ex(smd, false); BKE_ptcache_validate(cache, framenr); cache->flag &= ~PTCACHE_REDO_NEEDED; } |