diff --git a/core/audio.c b/core/audio.c index ad362657..10ed311b 100644 --- a/core/audio.c +++ b/core/audio.c @@ -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; } diff --git a/core/collection.c b/core/collection.c index 13a69c65..89578fe8 100644 --- a/core/collection.c +++ b/core/collection.c @@ -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; } diff --git a/core/containers/database.c b/core/containers/database.c index 86a4f426..96f74e65 100644 --- a/core/containers/database.c +++ b/core/containers/database.c @@ -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) diff --git a/core/idle.c b/core/idle.c index 3d1d9712..ef673263 100644 --- a/core/idle.c +++ b/core/idle.c @@ -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)) diff --git a/core/tempq.c b/core/tempq.c index 5ecd3413..09941d23 100644 --- a/core/tempq.c +++ b/core/tempq.c @@ -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; } diff --git a/gui/collection.c b/gui/collection.c index 31dd97a9..1a7c6282 100644 --- a/gui/collection.c +++ b/gui/collection.c @@ -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; } diff --git a/include/core/idle.h b/include/core/idle.h index 071231c5..0b3c12e5 100644 --- a/include/core/idle.h +++ b/include/core/idle.h @@ -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. diff --git a/tests/core/idle.c b/tests/core/idle.c index 0f025992..fe77156e 100644 --- a/tests/core/idle.c +++ b/tests/core/idle.c @@ -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; } diff --git a/tests/gui/idle.c b/tests/gui/idle.c index c2cd1495..370640b2 100644 --- a/tests/gui/idle.c +++ b/tests/gui/idle.c @@ -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()