8c8ab2a9eb
This function is used to cancel all idle tasks and free the memory allocated for them. This needs to be called when Ocarina is shutting down to prevent a possible hang with the gtk idle callback continuing to process tasks. Fixes #30: Closing Ocarina should cancel idle tasks Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
63 lines
1.0 KiB
C
63 lines
1.0 KiB
C
/*
|
|
* Copyright 2013 (c) Anna Schumaker.
|
|
*/
|
|
#include <core/idle.h>
|
|
|
|
#include <glib.h>
|
|
|
|
|
|
struct idle_task {
|
|
void (*idle_func)(void *);
|
|
void *idle_data;
|
|
};
|
|
|
|
static GQueue idle_queue = G_QUEUE_INIT;
|
|
static float queued = 0.0;
|
|
static float serviced = 0.0;
|
|
|
|
|
|
void idle_schedule(void (*func)(void *), void *data)
|
|
{
|
|
struct idle_task *task = g_malloc(sizeof(struct idle_task));
|
|
task->idle_func = func;
|
|
task->idle_data = data;
|
|
|
|
g_queue_push_tail(&idle_queue, task);
|
|
queued++;
|
|
}
|
|
|
|
bool idle_run_task()
|
|
{
|
|
struct idle_task *task;
|
|
|
|
if (!g_queue_is_empty(&idle_queue)) {
|
|
task = g_queue_pop_head(&idle_queue);
|
|
task->idle_func(task->idle_data);
|
|
g_free(task);
|
|
serviced++;
|
|
}
|
|
|
|
if (g_queue_is_empty(&idle_queue)) {
|
|
queued = 0.0;
|
|
serviced = 0.0;
|
|
}
|
|
return !g_queue_is_empty(&idle_queue);
|
|
}
|
|
|
|
float idle_progress()
|
|
{
|
|
if (g_queue_is_empty(&idle_queue))
|
|
return 1.0;
|
|
return serviced / queued;
|
|
}
|
|
|
|
void idle_cancel()
|
|
{
|
|
struct idle_task *task;
|
|
|
|
while (!g_queue_is_empty(&idle_queue)) {
|
|
task = g_queue_pop_head(&idle_queue);
|
|
g_free(task);
|
|
}
|
|
}
|