mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 12:32:52 +00:00
(tasks) Add wait/cancel functions and some documentation
This commit is contained in:
parent
5a158a18ce
commit
0496bed76e
@ -16,7 +16,8 @@ typedef struct {
|
||||
|
||||
struct rarch_task_impl {
|
||||
void (*push_running)(rarch_task_t *);
|
||||
void (*push_finished)(rarch_task_t *);
|
||||
void (*cancel)(void);
|
||||
void (*wait)(void);
|
||||
void (*gather)(void);
|
||||
void (*init)(void);
|
||||
void (*deinit)(void);
|
||||
@ -53,12 +54,9 @@ static rarch_task_t *task_queue_get(task_queue_t *queue)
|
||||
|
||||
static void rarch_task_internal_gather(void)
|
||||
{
|
||||
rarch_task_t *next = NULL;
|
||||
while ((next = task_queue_get(&tasks_finished)) != NULL)
|
||||
rarch_task_t *task;
|
||||
while ((task = task_queue_get(&tasks_finished)) != NULL)
|
||||
{
|
||||
rarch_task_t *task = next;
|
||||
next = next->next;
|
||||
|
||||
if (task->callback)
|
||||
task->callback(task->task_data, task->user_data, task->error);
|
||||
|
||||
@ -69,11 +67,6 @@ static void rarch_task_internal_gather(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void regular_push_finished(rarch_task_t *task)
|
||||
{
|
||||
task_queue_put(&tasks_finished, task);
|
||||
}
|
||||
|
||||
static void regular_push_running(rarch_task_t *task)
|
||||
{
|
||||
task_queue_put(&tasks_running, task);
|
||||
@ -99,7 +92,7 @@ static void regular_gather(void)
|
||||
task->handler(task);
|
||||
|
||||
if (task->finished)
|
||||
regular_push_finished(task);
|
||||
task_queue_put(&tasks_finished, task);
|
||||
else
|
||||
regular_push_running(task);
|
||||
}
|
||||
@ -107,6 +100,20 @@ static void regular_gather(void)
|
||||
rarch_task_internal_gather();
|
||||
}
|
||||
|
||||
static void regular_wait(void)
|
||||
{
|
||||
while (tasks_running.front)
|
||||
regular_gather();
|
||||
}
|
||||
|
||||
static void regular_cancel()
|
||||
{
|
||||
rarch_task_t *task;
|
||||
|
||||
for (task = tasks_running.front; task; task = task->next)
|
||||
task->cancelled = true;
|
||||
}
|
||||
|
||||
static void regular_init(void)
|
||||
{
|
||||
}
|
||||
@ -117,7 +124,8 @@ static void regular_deinit(void)
|
||||
|
||||
static struct rarch_task_impl impl_regular = {
|
||||
regular_push_running,
|
||||
regular_push_finished,
|
||||
regular_cancel,
|
||||
regular_wait,
|
||||
regular_gather,
|
||||
regular_init,
|
||||
regular_deinit
|
||||
@ -130,13 +138,6 @@ static scond_t *worker_cond = NULL;
|
||||
static sthread_t *worker_thread = NULL;
|
||||
static bool worker_continue = true; /* use running_lock when touching it */
|
||||
|
||||
static void threaded_push_finished(rarch_task_t *task)
|
||||
{
|
||||
slock_lock(finished_lock);
|
||||
task_queue_put(&tasks_finished, task);
|
||||
slock_unlock(finished_lock);
|
||||
}
|
||||
|
||||
static void threaded_push_running(rarch_task_t *task)
|
||||
{
|
||||
slock_lock(running_lock);
|
||||
@ -152,6 +153,29 @@ static void threaded_gather(void)
|
||||
slock_unlock(finished_lock);
|
||||
}
|
||||
|
||||
static void threaded_wait(void)
|
||||
{
|
||||
bool wait;
|
||||
do
|
||||
{
|
||||
threaded_gather();
|
||||
|
||||
slock_lock(running_lock);
|
||||
wait = (tasks_running.front != NULL);
|
||||
slock_unlock(running_lock);
|
||||
} while (wait);
|
||||
}
|
||||
|
||||
static void threaded_cancel(void)
|
||||
{
|
||||
rarch_task_t *task;
|
||||
|
||||
slock_lock(running_lock);
|
||||
for (task = tasks_running.front; task; task = task->next)
|
||||
task->cancelled = true;
|
||||
slock_unlock(running_lock);
|
||||
}
|
||||
|
||||
static void threaded_worker(void *userdata)
|
||||
{
|
||||
(void)userdata;
|
||||
@ -192,7 +216,11 @@ static void threaded_worker(void *userdata)
|
||||
task->handler(task);
|
||||
|
||||
if (task->finished)
|
||||
threaded_push_finished(task);
|
||||
{
|
||||
slock_lock(finished_lock);
|
||||
task_queue_put(&tasks_finished, task);
|
||||
slock_unlock(finished_lock);
|
||||
}
|
||||
else
|
||||
threaded_push_running(task);
|
||||
}
|
||||
@ -235,7 +263,8 @@ static void threaded_deinit(void)
|
||||
|
||||
static struct rarch_task_impl impl_threaded = {
|
||||
threaded_push_running,
|
||||
threaded_push_finished,
|
||||
threaded_cancel,
|
||||
threaded_wait,
|
||||
threaded_gather,
|
||||
threaded_init,
|
||||
threaded_deinit
|
||||
@ -282,7 +311,19 @@ void rarch_task_check(void)
|
||||
impl_current->gather();
|
||||
}
|
||||
|
||||
/* The lack of NULL checks in the following functions is proposital
|
||||
* to ensure correct control flow by the users. */
|
||||
void rarch_task_push(rarch_task_t *task)
|
||||
{
|
||||
impl_current->push_running(task);
|
||||
}
|
||||
|
||||
void rarch_task_wait(void)
|
||||
{
|
||||
impl_current->wait();
|
||||
}
|
||||
|
||||
void rarch_task_reset(void)
|
||||
{
|
||||
impl_current->cancel();
|
||||
}
|
||||
|
@ -37,9 +37,12 @@ struct rarch_task {
|
||||
rarch_task_handler_t handler;
|
||||
rarch_task_callback_t callback; /* always called from the main loop */
|
||||
|
||||
/* set by the handler */
|
||||
/* set to true by the handler to signal the task has finished executing. */
|
||||
bool finished;
|
||||
|
||||
/* set to true by the task system to signal the task *must* end. */
|
||||
bool cancelled;
|
||||
|
||||
/* created by the handler, destroyed by the user */
|
||||
void *task_data;
|
||||
|
||||
@ -56,12 +59,57 @@ struct rarch_task {
|
||||
rarch_task_t *next;
|
||||
};
|
||||
|
||||
/* MAIN THREAD ONLY */
|
||||
/**
|
||||
* @brief Initializes the task system
|
||||
*
|
||||
* This function initializes the task system and chooses an appropriate
|
||||
* implementation according to the settings.
|
||||
*
|
||||
* This function must only be called from the main thread.
|
||||
*/
|
||||
void rarch_task_init(void);
|
||||
|
||||
/**
|
||||
* @brief Deinitializes the task system
|
||||
*
|
||||
* This function deinitializes the task system. The tasks that are running at
|
||||
* the moment will stay on hold until rarch_task_init() is called again.
|
||||
*/
|
||||
void rarch_task_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Checks for finished tasks
|
||||
*
|
||||
* Takes the finished tasks, if any, and runs their callbacks.
|
||||
*
|
||||
* This function must only be called from the main thread.
|
||||
*/
|
||||
void rarch_task_check(void);
|
||||
|
||||
/* MAIN AND TASK THREADS */
|
||||
/**
|
||||
* @brief Sends a signal to terminate all the tasks.
|
||||
*
|
||||
* This function won't terminate the tasks immediately. They will finish as
|
||||
* soon as possible.
|
||||
*
|
||||
* This function must only be called from the main thread.
|
||||
*/
|
||||
void rarch_task_reset(void);
|
||||
|
||||
/**
|
||||
* @brief Blocks until all tasks have finished.
|
||||
*
|
||||
* This function must only be called from the main thread.
|
||||
*/
|
||||
void rarch_task_wait(void);
|
||||
|
||||
/**
|
||||
* @brief Pushes a task
|
||||
*
|
||||
* The task will start as soon as possible.
|
||||
*
|
||||
* @param task
|
||||
*/
|
||||
void rarch_task_push(rarch_task_t *task);
|
||||
|
||||
#ifdef HAVE_NETWORKING
|
||||
|
Loading…
x
Reference in New Issue
Block a user