mirror of
https://github.com/libretro/RetroArch
synced 2025-03-24 22:43:41 +00:00
Rewrite task_queue.c - get rid of messy internal Rarch code
This commit is contained in:
parent
ef0b15f3f4
commit
faf939856b
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
|
Loading…
x
Reference in New Issue
Block a user