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; return true;
} }
static void __audio_init_idle(void *data) static bool __audio_init_idle(void *data)
{ {
unsigned int track; unsigned int track;
@ -102,6 +102,7 @@ static void __audio_init_idle(void *data)
file_close(&audio_file); file_close(&audio_file);
__audio_load(track_get(track), GST_STATE_PAUSED); __audio_load(track_get(track), GST_STATE_PAUSED);
} }
return true;
} }

View File

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

View File

@ -129,9 +129,15 @@ void db_load(struct database *db)
file_close(&db->db_file); 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) 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) struct db_entry *db_insert(struct database *db, const gchar *key)

View File

@ -6,7 +6,7 @@
struct idle_task { struct idle_task {
void (*idle_func)(void *); bool (*idle_func)(void *);
void *idle_data; void *idle_data;
enum idle_sync_t idle_sync; enum idle_sync_t idle_sync;
}; };
@ -17,16 +17,20 @@ static unsigned int queued = 0;
static unsigned int serviced = 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); bool finished = task->idle_func(task->idle_data);
g_free(task); if (finished) {
g_atomic_int_inc(&serviced); g_free(task);
g_atomic_int_inc(&serviced);
}
return finished;
} }
void __idle_thread(gpointer task, gpointer data) 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; 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)); struct idle_task *task = g_malloc(sizeof(struct idle_task));
task->idle_func = func; task->idle_func = func;
@ -70,8 +74,8 @@ bool idle_run_task()
task = g_queue_pop_head(&idle_queue); task = g_queue_pop_head(&idle_queue);
if (task->idle_sync == IDLE_ASYNC) if (task->idle_sync == IDLE_ASYNC)
g_thread_pool_push(idle_pool, task, NULL); g_thread_pool_push(idle_pool, task, NULL);
else else if (!__idle_run_task(task))
__idle_run_task(task); g_queue_push_tail(&idle_queue, task);
} }
if (g_atomic_int_get(&queued) != g_atomic_int_get(&serviced)) 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"); file_writef(&tempq_file, "\n");
} }
static void __tempq_init_idle(void *data) static bool __tempq_init_idle(void *data)
{ {
unsigned int num, i; unsigned int num, i;
if (!file_open(&tempq_file, OPEN_READ)) if (!file_open(&tempq_file, OPEN_READ))
return; return true;
file_readf(&tempq_file, "%u", &num); file_readf(&tempq_file, "%u", &num);
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
__tempq_read_queue(); __tempq_read_queue();
file_close(&tempq_file); 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)); gui_sidebar_set_size(gui_queue(queue));
} }
void __gui_collection_init_idle() bool __gui_collection_init_idle()
{ {
struct db_entry *library, *next; struct db_entry *library, *next;
GtkTreeIter parent, iter, last; 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); gtk_tree_store_insert_before(GTK_TREE_STORE(c_model), &iter, &parent, &last);
__collection_set_library(&iter, LIBRARY(library)); __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. */ 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. */ /* Called to initialize the idle queue. */
@ -30,7 +30,7 @@ void idle_init();
void idle_deinit(); void idle_deinit();
/* Called to schedule a function to run later. */ /* 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. * Called to run the next task on the idle queue.

View File

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

View File

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