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:
parent
6b52775e58
commit
97c8f80393
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
22
core/idle.c
22
core/idle.c
|
@ -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))
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue