Fix race condition and bad memory access highlighting render tiles

Is was possible that interface will be refreshed at thesame time
as render engine will start freeing render parts.

Not sure if we can get away without RW mutex here, seems we need
one way of synchronization or another..
This commit is contained in:
Sergey Sharybin 2015-03-20 17:48:45 +05:00
parent c0be69f7fd
commit 3d6642db83
3 changed files with 15 additions and 2 deletions

@ -194,6 +194,7 @@ struct Render
struct Object *camera_override; struct Object *camera_override;
unsigned int lay, layer_override; unsigned int lay, layer_override;
ThreadRWMutex partsmutex;
ListBase parts; ListBase parts;
/* render engine */ /* render engine */

@ -375,9 +375,12 @@ void RE_engine_get_current_tiles(Render *re, int *total_tiles_r, rcti **tiles_r)
rcti *tiles = NULL; rcti *tiles = NULL;
int allocation_size = 0, allocation_step = BLENDER_MAX_THREADS; int allocation_size = 0, allocation_step = BLENDER_MAX_THREADS;
BLI_rw_mutex_lock(&re->partsmutex, THREAD_LOCK_READ);
if (re->engine && (re->engine->flag & RE_ENGINE_HIGHLIGHT_TILES) == 0) { if (re->engine && (re->engine->flag & RE_ENGINE_HIGHLIGHT_TILES) == 0) {
*total_tiles_r = 0; *total_tiles_r = 0;
*tiles_r = NULL; *tiles_r = NULL;
BLI_rw_mutex_unlock(&re->partsmutex);
return; return;
} }
@ -404,7 +407,7 @@ void RE_engine_get_current_tiles(Render *re, int *total_tiles_r, rcti **tiles_r)
total_tiles++; total_tiles++;
} }
} }
BLI_rw_mutex_unlock(&re->partsmutex);
*total_tiles_r = total_tiles; *total_tiles_r = total_tiles;
*tiles_r = tiles; *tiles_r = tiles;
} }
@ -478,6 +481,8 @@ bool RE_bake_engine(
engine->tile_y = 0; engine->tile_y = 0;
engine->flag &= ~RE_ENGINE_RENDERING; engine->flag &= ~RE_ENGINE_RENDERING;
BLI_rw_mutex_lock(&re->partsmutex, THREAD_LOCK_WRITE);
/* re->engine becomes zero if user changed active render engine during render */ /* re->engine becomes zero if user changed active render engine during render */
if (!persistent_data || !re->engine) { if (!persistent_data || !re->engine) {
RE_engine_free(engine); RE_engine_free(engine);
@ -485,6 +490,7 @@ bool RE_bake_engine(
} }
RE_parts_free(re); RE_parts_free(re);
BLI_rw_mutex_unlock(&re->partsmutex);
if (BKE_reports_contain(re->reports, RPT_ERROR)) if (BKE_reports_contain(re->reports, RPT_ERROR))
G.is_break = true; G.is_break = true;
@ -663,6 +669,8 @@ int RE_engine_render(Render *re, int do_all)
render_result_free_list(&engine->fullresult, engine->fullresult.first); render_result_free_list(&engine->fullresult, engine->fullresult.first);
BLI_rw_mutex_lock(&re->partsmutex, THREAD_LOCK_WRITE);
/* re->engine becomes zero if user changed active render engine during render */ /* re->engine becomes zero if user changed active render engine during render */
if (!persistent_data || !re->engine) { if (!persistent_data || !re->engine) {
RE_engine_free(engine); RE_engine_free(engine);
@ -682,6 +690,7 @@ int RE_engine_render(Render *re, int do_all)
} }
RE_parts_free(re); RE_parts_free(re);
BLI_rw_mutex_unlock(&re->partsmutex);
if (BKE_reports_contain(re->reports, RPT_ERROR)) if (BKE_reports_contain(re->reports, RPT_ERROR))
G.is_break = true; G.is_break = true;

@ -385,6 +385,7 @@ Render *RE_NewRender(const char *name)
BLI_addtail(&RenderGlobal.renderlist, re); BLI_addtail(&RenderGlobal.renderlist, re);
BLI_strncpy(re->name, name, RE_MAXNAME); BLI_strncpy(re->name, name, RE_MAXNAME);
BLI_rw_mutex_init(&re->resultmutex); BLI_rw_mutex_init(&re->resultmutex);
BLI_rw_mutex_init(&re->partsmutex);
re->eval_ctx = MEM_callocN(sizeof(EvaluationContext), "re->eval_ctx"); re->eval_ctx = MEM_callocN(sizeof(EvaluationContext), "re->eval_ctx");
re->eval_ctx->mode = DAG_EVAL_RENDER; re->eval_ctx->mode = DAG_EVAL_RENDER;
} }
@ -423,6 +424,7 @@ void RE_FreeRender(Render *re)
RE_engine_free(re->engine); RE_engine_free(re->engine);
BLI_rw_mutex_end(&re->resultmutex); BLI_rw_mutex_end(&re->resultmutex);
BLI_rw_mutex_end(&re->partsmutex);
BLI_freelistN(&re->r.layers); BLI_freelistN(&re->r.layers);
@ -1268,8 +1270,9 @@ static void threaded_tile_processor(Render *re)
/* unset threadsafety */ /* unset threadsafety */
g_break = 0; g_break = 0;
BLI_rw_mutex_lock(&re->partsmutex, THREAD_LOCK_WRITE);
RE_parts_free(re); RE_parts_free(re);
BLI_rw_mutex_unlock(&re->partsmutex);
re->viewplane = viewplane; /* restore viewplane, modified by pano render */ re->viewplane = viewplane; /* restore viewplane, modified by pano render */
} }