From dd98f6b55cdf7da3c60bb9278bcf4c9baeb49507 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Jun 2021 20:17:03 +1000 Subject: Fix missing free calls for task iterator A single threaded task with thread data over 8192 bytes would leak. While this didn't happen in practice, it could cause issues in the future. The free call for `task_parallel_iterator_do` wasn't running if callbacks weren't set, also not an issue in practice but avoids potential problems in the future too. --- source/blender/blenlib/intern/task_iterator.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/task_iterator.c b/source/blender/blenlib/intern/task_iterator.c index 85cd9718ed4..463d3675cbe 100644 --- a/source/blender/blenlib/intern/task_iterator.c +++ b/source/blender/blenlib/intern/task_iterator.c @@ -182,9 +182,12 @@ static void task_parallel_iterator_no_threads(const TaskParallelSettings *settin parallel_iterator_func_do(state, userdata_chunk); - if (use_userdata_chunk && settings->func_free != NULL) { - /* `func_free` should only free data that was created during execution of `func`. */ - settings->func_free(state->userdata, userdata_chunk_local); + if (use_userdata_chunk) { + if (settings->func_free != NULL) { + /* `func_free` should only free data that was created during execution of `func`. */ + settings->func_free(state->userdata, userdata_chunk_local); + } + MALLOCA_FREE(userdata_chunk_local, userdata_chunk_size); } } @@ -241,14 +244,16 @@ static void task_parallel_iterator_do(const TaskParallelSettings *settings, BLI_task_pool_work_and_wait(task_pool); BLI_task_pool_free(task_pool); - if (use_userdata_chunk && (settings->func_reduce != NULL || settings->func_free != NULL)) { - for (size_t i = 0; i < num_tasks; i++) { - userdata_chunk_local = (char *)userdata_chunk_array + (userdata_chunk_size * i); - if (settings->func_reduce != NULL) { - settings->func_reduce(state->userdata, userdata_chunk, userdata_chunk_local); - } - if (settings->func_free != NULL) { - settings->func_free(state->userdata, userdata_chunk_local); + if (use_userdata_chunk) { + if (settings->func_reduce != NULL || settings->func_free != NULL) { + for (size_t i = 0; i < num_tasks; i++) { + userdata_chunk_local = (char *)userdata_chunk_array + (userdata_chunk_size * i); + if (settings->func_reduce != NULL) { + settings->func_reduce(state->userdata, userdata_chunk, userdata_chunk_local); + } + if (settings->func_free != NULL) { + settings->func_free(state->userdata, userdata_chunk_local); + } } } MALLOCA_FREE(userdata_chunk_array, userdata_chunk_size * num_tasks); -- cgit v1.2.3