From cc4b5dbf3571d894f0130dfe52b633a971e0e3bc Mon Sep 17 00:00:00 2001 From: Sebastien Ronsse Date: Thu, 5 May 2016 09:41:30 +1000 Subject: [PATCH] task queue: Fix multi-threading issues in threaded worker --- libretro-common/queues/task_queue.c | 46 ++++++++++++++--------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/libretro-common/queues/task_queue.c b/libretro-common/queues/task_queue.c index e67905e7b5..3c4940a24a 100644 --- a/libretro-common/queues/task_queue.c +++ b/libretro-common/queues/task_queue.c @@ -321,24 +321,17 @@ static void threaded_worker(void *userdata) for (;;) { - retro_task_t *queue = NULL; retro_task_t *task = NULL; retro_task_t *next = NULL; - /* pop all into a local queue, - * tasks are in the reverse order here. */ - slock_lock(running_lock); - if (!worker_continue) break; /* should we keep running until all tasks finished? */ - while ((task = task_queue_get(&tasks_running)) != NULL) - { - task->next = queue; - queue = task; - } + slock_lock(running_lock); - if (queue == NULL) /* no tasks running, lets wait a bit */ + /* Get first task to run */ + task = tasks_running.front; + if (task == NULL) { scond_wait(worker_cond, running_lock); slock_unlock(running_lock); @@ -347,21 +340,26 @@ static void threaded_worker(void *userdata) slock_unlock(running_lock); - for (task = queue; task; task = next) - { - next = task->next; - task->handler(task); + task->handler(task); - if (task->finished) - { - slock_lock(finished_lock); - task_queue_put(&tasks_finished, task); - slock_unlock(finished_lock); - } - else - retro_task_threaded_push_running(task); + slock_lock(running_lock); + task_queue_remove(&tasks_running, task); + slock_unlock(running_lock); + + /* Update queue */ + if (!task->finished) + { + /* Re-add task to running queue */ + retro_task_threaded_push_running(task); } - + else + { + /* Add task to finished queue */ + slock_lock(finished_lock); + task_queue_put(&tasks_finished, task); + slock_unlock(finished_lock); + } + retro_sleep(10); }