Rewrite task_queue.c - get rid of messy internal Rarch code

This commit is contained in:
twinaphex 2017-01-03 18:26:52 +01:00
parent ef0b15f3f4
commit faf939856b
5 changed files with 96 additions and 84 deletions

View File

@ -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

View File

@ -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)

View File

@ -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:

View File

@ -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)

View File

@ -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))