diff --git a/libretro-common/queues/task_queue.c b/libretro-common/queues/task_queue.c index 792339b11a..d658f6b92f 100644 --- a/libretro-common/queues/task_queue.c +++ b/libretro-common/queues/task_queue.c @@ -313,23 +313,20 @@ static scond_t *worker_cond = NULL; static sthread_t *worker_thread = NULL; static bool worker_continue = true; /* use running_lock when touching it */ +/* 'queue_lock' must be held for the duration of this function */ static void task_queue_remove(task_queue_t *queue, retro_task_t *task) { retro_task_t *t = NULL; retro_task_t *front = NULL; - slock_lock(queue_lock); front = queue->front; - slock_unlock(queue_lock); /* Remove first element if needed */ if (task == front) { - slock_lock(queue_lock); queue->front = task->next; if (queue->back == task) /* if only element, also update back */ queue->back = NULL; - slock_unlock(queue_lock); task->next = NULL; return; } @@ -348,10 +345,8 @@ static void task_queue_remove(task_queue_t *queue, retro_task_t *task) /* When removing the tail of the queue, update the tail pointer */ if (queue->back == task) { - slock_lock(queue_lock); if (queue->back == task) queue->back = t; - slock_unlock(queue_lock); } break; } @@ -517,6 +512,7 @@ static void threaded_worker(void *userdata) { task_queue_remove(&tasks_running, task); task_queue_put(&tasks_running, task); + scond_signal(worker_cond); } slock_unlock(queue_lock); slock_unlock(running_lock); @@ -525,7 +521,9 @@ static void threaded_worker(void *userdata) { /* Remove task from running queue */ slock_lock(running_lock); + slock_lock(queue_lock); task_queue_remove(&tasks_running, task); + slock_unlock(queue_lock); slock_unlock(running_lock); /* Add task to finished queue */