diff options
author | Max Kellermann <max@duempel.org> | 2008-09-23 12:08:53 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2008-09-23 12:08:53 +0200 |
commit | a03216c4dd0d06da63a5040bbb1dce9212fc0271 (patch) | |
tree | 2b3b44fceacbce2f8ac59a2c18c446d8963ed4c8 /src/lyrics.c | |
parent | 20e286dd6ccd108b1d1a41169059d0db8022b158 (diff) | |
download | mpd-a03216c4dd0d06da63a5040bbb1dce9212fc0271.tar.gz mpd-a03216c4dd0d06da63a5040bbb1dce9212fc0271.tar.xz mpd-a03216c4dd0d06da63a5040bbb1dce9212fc0271.zip |
lyrics: added callback
Instead of letting our caller poll lyrics_result(), call it back as
soon as we have the result.
Diffstat (limited to 'src/lyrics.c')
-rw-r--r-- | src/lyrics.c | 55 |
1 files changed, 31 insertions, 24 deletions
diff --git a/src/lyrics.c b/src/lyrics.c index 917344701..7a6124b69 100644 --- a/src/lyrics.c +++ b/src/lyrics.c @@ -32,7 +32,8 @@ static GPtrArray *plugins; struct lyrics_loader { char *artist, *title; - enum lyrics_loader_result result; + lyrics_callback_t callback; + void *callback_data; guint next_plugin; @@ -99,7 +100,7 @@ lyrics_eof(struct lyrics_loader *loader) lyrics_next_plugin(loader); } else { - loader->result = LYRICS_SUCCESS; + loader->callback(loader->data, loader->callback_data); } } @@ -112,7 +113,6 @@ lyrics_data(mpd_unused GIOChannel *source, ssize_t nbytes; assert(loader != NULL); - assert(loader->result = LYRICS_BUSY); assert(loader->fd >= 0); assert(loader->pid > 0); assert(source == loader->channel); @@ -134,6 +134,28 @@ lyrics_data(mpd_unused GIOChannel *source, return TRUE; } +/** + * This is a timer callback which calls the lyrics callback "some + * timer later". This solves the problem that lyrics_load() may fail + * immediately, leaving its return value in an undefined state. + * Instead, install a timer which calls the lyrics callback in the + * moment after. + */ +static gboolean +lyrics_delayed_fail(gpointer data) +{ + struct lyrics_loader *loader = data; + + assert(loader != NULL); + assert(loader->fd < 0); + assert(loader->pid < 0); + assert(loader->data == NULL); + + loader->callback(NULL, loader->callback_data); + + return FALSE; +} + static int lyrics_start_plugin(struct lyrics_loader *loader, const char *plugin_path) { @@ -141,7 +163,6 @@ lyrics_start_plugin(struct lyrics_loader *loader, const char *plugin_path) pid_t pid; assert(loader != NULL); - assert(loader->result == LYRICS_BUSY); assert(loader->pid < 0); assert(loader->fd < 0); assert(loader->data == NULL); @@ -198,7 +219,7 @@ lyrics_next_plugin(struct lyrics_loader *loader) if (loader->next_plugin >= plugins->len) { /* no plugins left */ - loader->result = LYRICS_FAILED; + g_timeout_add(0, lyrics_delayed_fail, loader); return; } @@ -206,13 +227,14 @@ lyrics_next_plugin(struct lyrics_loader *loader) ret = lyrics_start_plugin(loader, plugin_path); if (ret < 0) { /* system error */ - loader->result = LYRICS_FAILED; + g_timeout_add(0, lyrics_delayed_fail, loader); return; } } struct lyrics_loader * -lyrics_load(const char *artist, const char *title) +lyrics_load(const char *artist, const char *title, + lyrics_callback_t callback, void *data) { struct lyrics_loader *loader = g_new(struct lyrics_loader, 1); @@ -224,7 +246,8 @@ lyrics_load(const char *artist, const char *title) loader->artist = g_strdup(artist); loader->title = g_strdup(title); - loader->result = LYRICS_BUSY; + loader->callback = callback; + loader->data = data; loader->next_plugin = 0; loader->pid = -1; loader->fd = -1; @@ -254,19 +277,3 @@ lyrics_free(struct lyrics_loader *loader) if (loader->data != NULL) g_string_free(loader->data, TRUE); } - -enum lyrics_loader_result -lyrics_result(struct lyrics_loader *loader) -{ - return loader->result; -} - -const GString * -lyrics_get(struct lyrics_loader *loader) -{ - assert(loader->result == LYRICS_SUCCESS); - assert(loader->pid < 0); - assert(loader->data != NULL); - - return loader->data; -} |