diff --git a/libretro-common/queues/task_queue.c b/libretro-common/queues/task_queue.c index 489593e218..3c4940a24a 100644 --- a/libretro-common/queues/task_queue.c +++ b/libretro-common/queues/task_queue.c @@ -113,6 +113,35 @@ static retro_task_t *task_queue_get(task_queue_t *queue) return task; } +static void task_queue_remove(task_queue_t *queue, retro_task_t *task) +{ + retro_task_t *t; + + /* Remove first element if needed */ + if (task == queue->front) + { + queue->front = task->next; + task->next = NULL; + return; + } + + /* Parse queue */ + t = queue->front; + while (t && t->next) + { + /* Remove task and update queue */ + if (t->next == task) + { + t->next = task->next; + task->next = NULL; + break; + } + + /* Update iterator */ + t = t->next; + } +} + static void retro_task_internal_gather(void) { retro_task_t *task = NULL; @@ -292,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); @@ -318,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); } diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index fc1d1f444b..fba8fccd12 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -1379,6 +1379,19 @@ static void cb_generic_download(void *task_data, fill_pathname_join(output_path, dir_path, transf->path, sizeof(output_path)); +#ifdef HAVE_ZLIB + file_ext = path_get_extension(output_path); + + if (string_is_equal_noncase(file_ext, "zip")) + { + if (rarch_task_check_decompress(output_path)) + { + err = "Decompression already in progress."; + goto finish; + } + } +#endif + if (!filestream_write_file(output_path, data->data, data->len)) { err = "Write failed."; @@ -1386,8 +1399,6 @@ static void cb_generic_download(void *task_data, } #ifdef HAVE_ZLIB - file_ext = path_get_extension(output_path); - if (!settings->network.buildbot_auto_extract_archive) goto finish; diff --git a/tasks/task_decompress.c b/tasks/task_decompress.c index 3e383b5c96..104725c831 100644 --- a/tasks/task_decompress.c +++ b/tasks/task_decompress.c @@ -226,6 +226,18 @@ static bool rarch_task_decompress_finder( return string_is_equal(dec->source_file, (const char*)user_data); } +bool rarch_task_check_decompress(const char *source_file) +{ + task_finder_data_t find_data; + + /* Prepare find parameters */ + find_data.func = rarch_task_decompress_finder; + find_data.userdata = (void *)source_file; + + /* Return whether decompressing is in progress or not */ + return task_queue_ctl(TASK_QUEUE_CTL_FIND, &find_data); +} + bool rarch_task_push_decompress( const char *source_file, const char *target_dir, @@ -235,7 +247,6 @@ bool rarch_task_push_decompress( retro_task_callback_t cb, void *user_data) { - task_finder_data_t find_data; char tmp[PATH_MAX_LENGTH]; decompress_state_t *s = NULL; retro_task_t *t = NULL; @@ -263,10 +274,7 @@ bool rarch_task_push_decompress( if (!valid_ext || !valid_ext[0]) valid_ext = NULL; - find_data.func = rarch_task_decompress_finder; - find_data.userdata = (void*)source_file; - - if (task_queue_ctl(TASK_QUEUE_CTL_FIND, &find_data)) + if (rarch_task_check_decompress(source_file)) { RARCH_LOG("[decompress] File '%s' already being decompressed.\n", source_file); diff --git a/tasks/task_http.c b/tasks/task_http.c index f7d9bbfc2d..c17d2c465d 100644 --- a/tasks/task_http.c +++ b/tasks/task_http.c @@ -45,6 +45,7 @@ typedef struct http_handle struct http_connection_t *handle; transfer_cb_t cb; char elem1[PATH_MAX_LENGTH]; + char url[PATH_MAX_LENGTH]; } connection; struct http_t *handle; transfer_cb_t cb; @@ -192,20 +193,19 @@ task_finished: static bool rarch_task_http_finder(retro_task_t *task, void *user_data) { - http_handle_t *http = (http_handle_t*)task->state; - const char *handle_url = NULL; - if ( !http || !user_data || - !task || task->handler != rarch_task_http_transfer_handler) - return false; - if (!http->connection.handle) + http_handle_t *http; + + if (!task || (task->handler != rarch_task_http_transfer_handler)) return false; - handle_url = net_http_connection_url(http->connection.handle); - - if (!handle_url) + if (!user_data) return false; - return string_is_equal(handle_url, (const char*)user_data); + http = (http_handle_t*)task->state; + if (!http) + return false; + + return string_is_equal(http->connection.url, (const char*)user_data); } bool rarch_task_push_http_transfer(const char *url, const char *type, @@ -246,6 +246,8 @@ bool rarch_task_push_http_transfer(const char *url, const char *type, if (type) strlcpy(http->connection.elem1, type, sizeof(http->connection.elem1)); + strlcpy(http->connection.url, url, sizeof(http->connection.url)); + http->status = HTTP_STATUS_CONNECTION_TRANSFER; t = (retro_task_t*)calloc(1, sizeof(*t)); diff --git a/tasks/tasks_internal.h b/tasks/tasks_internal.h index 25e881e6b9..3fb56d67ce 100644 --- a/tasks/tasks_internal.h +++ b/tasks/tasks_internal.h @@ -61,6 +61,8 @@ int detect_ps1_game(const char *track_path, char *game_id); int detect_psp_game(const char *track_path, char *game_id); +bool rarch_task_check_decompress(const char *source_file); + bool rarch_task_push_decompress( const char *source_file, const char *target_dir,