task queue: Fix multi-threading issues in threaded worker

This commit is contained in:
Sebastien Ronsse 2016-05-05 09:41:30 +10:00
parent d3c3d20994
commit cc4b5dbf35

View File

@ -321,24 +321,17 @@ static void threaded_worker(void *userdata)
for (;;) for (;;)
{ {
retro_task_t *queue = NULL;
retro_task_t *task = NULL; retro_task_t *task = NULL;
retro_task_t *next = 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) if (!worker_continue)
break; /* should we keep running until all tasks finished? */ break; /* should we keep running until all tasks finished? */
while ((task = task_queue_get(&tasks_running)) != NULL) slock_lock(running_lock);
{
task->next = queue;
queue = task;
}
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); scond_wait(worker_cond, running_lock);
slock_unlock(running_lock); slock_unlock(running_lock);
@ -347,21 +340,26 @@ static void threaded_worker(void *userdata)
slock_unlock(running_lock); slock_unlock(running_lock);
for (task = queue; task; task = next) task->handler(task);
{
next = task->next;
task->handler(task);
if (task->finished) slock_lock(running_lock);
{ task_queue_remove(&tasks_running, task);
slock_lock(finished_lock); slock_unlock(running_lock);
task_queue_put(&tasks_finished, task);
slock_unlock(finished_lock); /* Update queue */
} if (!task->finished)
else {
retro_task_threaded_push_running(task); /* 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); retro_sleep(10);
} }