From faf939856b7ad90ad8b24a8168758271f2da8a43 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 3 Jan 2017 18:26:52 +0100 Subject: [PATCH] Rewrite task_queue.c - get rid of messy internal Rarch code --- libretro-common/include/queues/task_queue.h | 48 ++++---- libretro-common/queues/task_queue.c | 120 ++++++++++---------- menu/menu_setting.c | 4 +- runloop.c | 6 +- tasks/task_http.c | 2 +- 5 files changed, 96 insertions(+), 84 deletions(-) diff --git a/libretro-common/include/queues/task_queue.h b/libretro-common/include/queues/task_queue.h index ae0f0625dc..36369e9fcf 100644 --- a/libretro-common/include/queues/task_queue.h +++ b/libretro-common/include/queues/task_queue.h @@ -42,25 +42,11 @@ enum task_type TASK_TYPE_BLOCKING }; + enum task_queue_ctl_state { TASK_QUEUE_CTL_NONE = 0, - /* Deinitializes the task system. - * This deinitializes the task system. - * The tasks that are running at - * the moment will stay on hold - * until TASK_QUEUE_CTL_INIT is called again. */ - TASK_QUEUE_CTL_DEINIT, - - /* Initializes the task system. - * This initializes the task system - * and chooses an appropriate - * implementation according to the settings. - * - * This must only be called from the main thread. */ - TASK_QUEUE_CTL_INIT, - /** * Calls func for every running task * until it returns true. @@ -98,12 +84,6 @@ enum task_queue_ctl_state * This must only be called from the main thread. */ TASK_QUEUE_CTL_RESET, - TASK_QUEUE_CTL_SET_THREADED, - - TASK_QUEUE_CTL_UNSET_THREADED, - - TASK_QUEUE_CTL_IS_THREADED, - /** * Signals a task to end without waiting for * it to complete. */ @@ -119,6 +99,9 @@ typedef void (*retro_task_handler_t)(retro_task_t *task); typedef bool (*retro_task_finder_t)(retro_task_t *task, void *userdata); +typedef void (*retro_task_queue_msg_t)(const char *msg, + unsigned prio, unsigned duration, bool flush); + typedef bool (*retro_task_retriever_t)(retro_task_t *task, void *data); typedef struct @@ -200,6 +183,9 @@ void *task_queue_retriever_info_next(task_retriever_info_t **link); void task_queue_retriever_info_free(task_retriever_info_t *list); +/** + * Signals a task to end without waiting for + * it to complete. */ void task_queue_cancel_task(void *task); void task_set_finished(retro_task_t *task, bool finished); @@ -232,6 +218,26 @@ char* task_get_title(retro_task_t *task); void* task_get_data(retro_task_t *task); +void task_queue_set_threaded(void); + +void task_queue_unset_threaded(void); + +bool task_queue_is_threaded(void); + +/* Deinitializes the task system. + * This deinitializes the task system. + * The tasks that are running at + * the moment will stay on hold */ +void task_queue_deinit(void); + +/* Initializes the task system. + * This initializes the task system + * and chooses an appropriate + * implementation according to the settings. + * + * This must only be called from the main thread. */ +void task_queue_init(bool threaded, retro_task_queue_msg_t msg_push); + RETRO_END_DECLS #endif diff --git a/libretro-common/queues/task_queue.c b/libretro-common/queues/task_queue.c index fb47251de1..f228441280 100644 --- a/libretro-common/queues/task_queue.c +++ b/libretro-common/queues/task_queue.c @@ -43,6 +43,7 @@ typedef struct struct retro_task_impl { + retro_task_queue_msg_t msg_push; void (*push_running)(retro_task_t *); void (*cancel)(void *); void (*reset)(void); @@ -57,13 +58,13 @@ struct retro_task_impl static task_queue_t tasks_running = {NULL, NULL}; static task_queue_t tasks_finished = {NULL, NULL}; -static void task_queue_msg_push(unsigned prio, unsigned duration, +static struct retro_task_impl *impl_current = NULL; +static bool task_threaded_enable = false; + +static void task_queue_msg_push(retro_task_t *task, + unsigned prio, unsigned duration, bool flush, const char *fmt, ...) { -#ifdef RARCH_INTERNAL - extern void runloop_msg_queue_push(const char *msg, unsigned prio, - unsigned duration, bool flush); -#endif char buf[1024]; va_list ap; @@ -73,12 +74,8 @@ static void task_queue_msg_push(unsigned prio, unsigned duration, vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); - /* print something here */ - -#ifdef RARCH_INTERNAL - /* TODO/FIXME - ugly */ - runloop_msg_queue_push(buf, prio, duration, flush); -#endif + if (impl_current->msg_push) + impl_current->msg_push(buf, prio, duration, flush); } static void task_queue_push_progress(retro_task_t *task) @@ -88,18 +85,18 @@ static void task_queue_push_progress(retro_task_t *task) if (task->finished) { if (task->error) - task_queue_msg_push(1, 60, true, "%s: %s", + task_queue_msg_push(task, 1, 60, true, "%s: %s", "Task failed", task->title); else - task_queue_msg_push(1, 60, false, "100%%: %s", task->title); + task_queue_msg_push(task, 1, 60, false, "100%%: %s", task->title); } else { if (task->progress >= 0 && task->progress <= 100) - task_queue_msg_push(1, 60, false, "%i%%: %s", + task_queue_msg_push(task, 1, 60, false, "%i%%: %s", task->progress, task->title); else - task_queue_msg_push(1, 60, false, "%s...", task->title); + task_queue_msg_push(task, 1, 60, false, "%s...", task->title); } } } @@ -271,6 +268,7 @@ static void retro_task_regular_retrieve(task_retriever_data_t *data) } static struct retro_task_impl impl_regular = { + NULL, retro_task_regular_push_running, retro_task_regular_cancel, retro_task_regular_reset, @@ -521,6 +519,7 @@ static void retro_task_threaded_deinit(void) } static struct retro_task_impl impl_threaded = { + NULL, retro_task_threaded_push_running, retro_task_threaded_cancel, retro_task_threaded_reset, @@ -533,44 +532,52 @@ static struct retro_task_impl impl_threaded = { }; #endif +/* Deinitializes the task system. + * This deinitializes the task system. + * The tasks that are running at + * the moment will stay on hold */ +void task_queue_deinit(void) +{ + if (impl_current) + impl_current->deinit(); + impl_current = NULL; +} + +void task_queue_init(bool threaded, retro_task_queue_msg_t msg_push) +{ + impl_current = &impl_regular; + +#ifdef HAVE_THREADS + if (threaded) + { + task_threaded_enable = true; + impl_current = &impl_threaded; + } +#endif + + impl_current->msg_push = msg_push; + impl_current->init(); +} + +void task_queue_set_threaded(void) +{ + task_threaded_enable = true; +} + +void task_queue_unset_threaded(void) +{ + task_threaded_enable = false; +} + +bool task_queue_is_threaded(void) +{ + return task_threaded_enable; +} + bool task_queue_ctl(enum task_queue_ctl_state state, void *data) { - static struct retro_task_impl *impl_current = NULL; - static bool task_threaded_enable = false; - switch (state) { - case TASK_QUEUE_CTL_DEINIT: - if (impl_current) - impl_current->deinit(); - impl_current = NULL; - break; - case TASK_QUEUE_CTL_SET_THREADED: - task_threaded_enable = true; - break; - case TASK_QUEUE_CTL_UNSET_THREADED: - task_threaded_enable = false; - break; - case TASK_QUEUE_CTL_IS_THREADED: - return task_threaded_enable; - case TASK_QUEUE_CTL_INIT: - { -#ifdef HAVE_THREADS - bool *boolean_val = (bool*)data; -#endif - - impl_current = &impl_regular; -#ifdef HAVE_THREADS - if (boolean_val && *boolean_val) - { - task_queue_ctl(TASK_QUEUE_CTL_SET_THREADED, NULL); - impl_current = &impl_threaded; - } -#endif - - impl_current->init(); - } - break; case TASK_QUEUE_CTL_FIND: { task_finder_data_t *find_data = (task_finder_data_t*)data; @@ -585,14 +592,13 @@ bool task_queue_ctl(enum task_queue_ctl_state state, void *data) { #ifdef HAVE_THREADS bool current_threaded = (impl_current == &impl_threaded); - bool want_threaded = - task_queue_ctl(TASK_QUEUE_CTL_IS_THREADED, NULL); + bool want_threaded = task_queue_is_threaded(); if (want_threaded != current_threaded) - task_queue_ctl(TASK_QUEUE_CTL_DEINIT, NULL); + task_queue_deinit(); if (!impl_current) - task_queue_ctl(TASK_QUEUE_CTL_INIT, NULL); + task_queue_init(want_threaded, impl_current->msg_push); #endif impl_current->gather(); @@ -638,9 +644,6 @@ bool task_queue_ctl(enum task_queue_ctl_state state, void *data) case TASK_QUEUE_CTL_WAIT: impl_current->wait(); break; - case TASK_QUEUE_CTL_CANCEL: - impl_current->cancel(data); - break; case TASK_QUEUE_CTL_NONE: default: break; @@ -649,9 +652,12 @@ bool task_queue_ctl(enum task_queue_ctl_state state, void *data) return true; } +/** + * Signals a task to end without waiting for + * it to complete. */ void task_queue_cancel_task(void *task) { - task_queue_ctl(TASK_QUEUE_CTL_CANCEL, task); + impl_current->cancel(task); } void *task_queue_retriever_info_next(task_retriever_info_t **link) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index c52dd5f612..bacc866d20 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -1561,9 +1561,9 @@ void general_write_handler(void *data) case MENU_ENUM_LABEL_VIDEO_THREADED: { if (*setting->value.target.boolean) - task_queue_ctl(TASK_QUEUE_CTL_SET_THREADED, NULL); + task_queue_set_threaded(); else - task_queue_ctl(TASK_QUEUE_CTL_UNSET_THREADED, NULL); + task_queue_unset_threaded(); } break; case MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR: diff --git a/runloop.c b/runloop.c index 78dbc92dd5..de6ae19288 100644 --- a/runloop.c +++ b/runloop.c @@ -557,8 +557,8 @@ bool runloop_ctl(enum runloop_ctl_state state, void *data) #else bool threaded_enable = false; #endif - task_queue_ctl(TASK_QUEUE_CTL_DEINIT, NULL); - task_queue_ctl(TASK_QUEUE_CTL_INIT, &threaded_enable); + task_queue_deinit(); + task_queue_init(threaded_enable, runloop_msg_queue_push); } break; case RUNLOOP_CTL_SET_CORE_SHUTDOWN: @@ -573,7 +573,7 @@ bool runloop_ctl(enum runloop_ctl_state state, void *data) runloop_exec = true; break; case RUNLOOP_CTL_DATA_DEINIT: - task_queue_ctl(TASK_QUEUE_CTL_DEINIT, NULL); + task_queue_deinit(); break; case RUNLOOP_CTL_IS_CORE_OPTION_UPDATED: if (!runloop_core_options) diff --git a/tasks/task_http.c b/tasks/task_http.c index 0f78224b3c..343172202a 100644 --- a/tasks/task_http.c +++ b/tasks/task_http.c @@ -119,7 +119,7 @@ static int task_http_iterate_transfer(retro_task_t *task) size_t pos = 0, tot = 0; /* FIXME: This wouldn't be needed if we could wait for a timeout */ - if (task_queue_ctl(TASK_QUEUE_CTL_IS_THREADED, NULL)) + if (task_queue_is_threaded()) retro_sleep(1); if (!net_http_update(http->handle, &pos, &tot))