core/idle: Add a way to reschedule idle tasks

This will be needed to reschedule MusicBrainz requests if the server is
busy.

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2016-05-02 18:42:38 -04:00
parent 6b52775e58
commit 97c8f80393
9 changed files with 42 additions and 23 deletions

View File

@ -93,7 +93,7 @@ static gboolean __audio_message(GstBus *bus, GstMessage *message, gpointer data)
return true;
}
static void __audio_init_idle(void *data)
static bool __audio_init_idle(void *data)
{
unsigned int track;
@ -102,6 +102,7 @@ static void __audio_init_idle(void *data)
file_close(&audio_file);
__audio_load(track_get(track), GST_STATE_PAUSED);
}
return true;
}

View File

@ -18,7 +18,7 @@ struct scan_data {
gchar *sd_path;
};
static void __scan_dir(void *);
static bool __scan_dir(void *);
#ifdef CONFIG_TESTING
@ -61,7 +61,7 @@ static void __scan_path(struct scan_data *scan, const gchar *name)
g_free(path);
}
static void __scan_dir(void *data)
static bool __scan_dir(void *data)
{
struct scan_data *scan = data;
const char *name;
@ -84,9 +84,10 @@ out:
/* Allocated by __scan_dir_later() */
g_free(scan->sd_path);
g_free(scan);
return true;
}
static void __validate_library(void *data)
static bool __validate_library(void *data)
{
struct library *library = data;
struct db_entry *dbe, *next;
@ -105,14 +106,16 @@ static void __validate_library(void *data)
if (access < 0) {
if (collection_check_library(library) < 0)
return;
return true;
queue_remove_all(&c_queue, track);
track_remove(track);
}
}
return true;
}
void __collection_init_idle(void *data)
bool __collection_init_idle(void *data)
{
struct db_entry *track, *next;
unsigned int i, n = 0;
@ -146,6 +149,7 @@ void __collection_init_idle(void *data)
queue_set_flag(&c_queue, Q_SAVE_FLAGS);
collection_update_all();
return true;
}

View File

@ -129,9 +129,15 @@ void db_load(struct database *db)
file_close(&db->db_file);
}
static bool __db_load_idle(struct database *db)
{
db_load(db);
return true;
}
void db_load_idle(struct database *db)
{
idle_schedule(IDLE_SYNC, IDLE_FUNC(db_load), db);
idle_schedule(IDLE_SYNC, IDLE_FUNC(__db_load_idle), db);
}
struct db_entry *db_insert(struct database *db, const gchar *key)

View File

@ -6,7 +6,7 @@
struct idle_task {
void (*idle_func)(void *);
bool (*idle_func)(void *);
void *idle_data;
enum idle_sync_t idle_sync;
};
@ -17,16 +17,20 @@ static unsigned int queued = 0;
static unsigned int serviced = 0;
void __idle_run_task(struct idle_task *task)
bool __idle_run_task(struct idle_task *task)
{
task->idle_func(task->idle_data);
g_free(task);
g_atomic_int_inc(&serviced);
bool finished = task->idle_func(task->idle_data);
if (finished) {
g_free(task);
g_atomic_int_inc(&serviced);
}
return finished;
}
void __idle_thread(gpointer task, gpointer data)
{
__idle_run_task(task);
if (!__idle_run_task(task))
g_thread_pool_push(idle_pool, task, NULL);
}
@ -51,7 +55,7 @@ void idle_deinit()
serviced = 0;
}
void idle_schedule(enum idle_sync_t sync, void (*func)(void *), void *data)
void idle_schedule(enum idle_sync_t sync, bool (*func)(void *), void *data)
{
struct idle_task *task = g_malloc(sizeof(struct idle_task));
task->idle_func = func;
@ -70,8 +74,8 @@ bool idle_run_task()
task = g_queue_pop_head(&idle_queue);
if (task->idle_sync == IDLE_ASYNC)
g_thread_pool_push(idle_pool, task, NULL);
else
__idle_run_task(task);
else if (!__idle_run_task(task))
g_queue_push_tail(&idle_queue, task);
}
if (g_atomic_int_get(&queued) != g_atomic_int_get(&serviced))

View File

@ -57,17 +57,18 @@ static void __tempq_write_queue(struct queue *queue)
file_writef(&tempq_file, "\n");
}
static void __tempq_init_idle(void *data)
static bool __tempq_init_idle(void *data)
{
unsigned int num, i;
if (!file_open(&tempq_file, OPEN_READ))
return;
return true;
file_readf(&tempq_file, "%u", &num);
for (i = 0; i < num; i++)
__tempq_read_queue();
file_close(&tempq_file);
return true;
}

View File

@ -191,7 +191,7 @@ static void __collection_removed(struct queue *queue, unsigned int pos)
gui_sidebar_set_size(gui_queue(queue));
}
void __gui_collection_init_idle()
bool __gui_collection_init_idle()
{
struct db_entry *library, *next;
GtkTreeIter parent, iter, last;
@ -206,6 +206,7 @@ void __gui_collection_init_idle()
gtk_tree_store_insert_before(GTK_TREE_STORE(c_model), &iter, &parent, &last);
__collection_set_library(&iter, LIBRARY(library));
}
return true;
}

View File

@ -20,7 +20,7 @@ enum idle_sync_t {
IDLE_ASYNC, /* Run task in a separate thread. */
};
#define IDLE_FUNC(x) ((void (*)(void *))x)
#define IDLE_FUNC(x) ((bool (*)(void *))x)
/* Called to initialize the idle queue. */
@ -30,7 +30,7 @@ void idle_init();
void idle_deinit();
/* Called to schedule a function to run later. */
void idle_schedule(enum idle_sync_t, void (*)(void *), void *);
void idle_schedule(enum idle_sync_t, bool (*)(void *), void *);
/*
* Called to run the next task on the idle queue.

View File

@ -9,11 +9,12 @@
static unsigned int cur = -1;
static bool func_passed = false;
static void inc_cur(void *data)
static bool inc_cur(void *data)
{
unsigned int expected = GPOINTER_TO_INT(data);
cur++;
func_passed = (cur == expected);
return true;
}

View File

@ -18,11 +18,12 @@ static bool func_passed = false;
struct core_init_data init_data;
static GMainLoop *main_loop;
static void inc_cur(void *data)
static bool inc_cur(void *data)
{
unsigned int expected = GPOINTER_TO_INT(data);
cur++;
func_passed = (cur == expected);
return true;
}
static int test_on_idle()