From 754f26a97c816781e80500d98f2515ae97836145 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 14 Sep 2011 21:46:41 +0200 Subject: input_stream: non-blocking I/O Add GMutex, GCond attributes which will be used by callers to conditionally wait on the stream. Remove the (now-useless) plugin method buffer(), wait on GCond instead. Lock the input_stream before each method call. Do the same with the playlist plugins. --- src/playlist/asx_playlist_plugin.c | 3 ++- src/playlist/cue_playlist_plugin.c | 3 ++- src/playlist/despotify_playlist_plugin.c | 3 ++- src/playlist/flac_playlist_plugin.c | 3 ++- src/playlist/lastfm_playlist_plugin.c | 45 ++++++++++++-------------------- src/playlist/pls_playlist_plugin.c | 3 ++- src/playlist/rss_playlist_plugin.c | 3 ++- src/playlist/xspf_playlist_plugin.c | 3 ++- 8 files changed, 30 insertions(+), 36 deletions(-) (limited to 'src/playlist') diff --git a/src/playlist/asx_playlist_plugin.c b/src/playlist/asx_playlist_plugin.c index b711f83f..29868785 100644 --- a/src/playlist/asx_playlist_plugin.c +++ b/src/playlist/asx_playlist_plugin.c @@ -233,7 +233,8 @@ asx_open_stream(struct input_stream *is) &parser, asx_parser_destroy); while (true) { - nbytes = input_stream_read(is, buffer, sizeof(buffer), &error); + nbytes = input_stream_lock_read(is, buffer, sizeof(buffer), + &error); if (nbytes == 0) { if (error != NULL) { g_markup_parse_context_free(context); diff --git a/src/playlist/cue_playlist_plugin.c b/src/playlist/cue_playlist_plugin.c index e3619a28..3f2d5b34 100644 --- a/src/playlist/cue_playlist_plugin.c +++ b/src/playlist/cue_playlist_plugin.c @@ -41,7 +41,8 @@ struct cue_playlist { }; static struct playlist_provider * -cue_playlist_open_uri(const char *uri) +cue_playlist_open_uri(const char *uri, + G_GNUC_UNUSED GMutex *mutex, G_GNUC_UNUSED GCond *cond) { struct cue_playlist *playlist; FILE *file; diff --git a/src/playlist/despotify_playlist_plugin.c b/src/playlist/despotify_playlist_plugin.c index 39448e01..08a32d79 100644 --- a/src/playlist/despotify_playlist_plugin.c +++ b/src/playlist/despotify_playlist_plugin.c @@ -110,7 +110,8 @@ despotify_playlist_finish(void) static struct playlist_provider * -despotify_playlist_open_uri(const char *url) +despotify_playlist_open_uri(const char *url, G_GNUC_UNUSED GMutex *mutex, + G_GNUC_UNUSED GCond *cond) { struct despotify_playlist *ctx; struct despotify_session *session; diff --git a/src/playlist/flac_playlist_plugin.c b/src/playlist/flac_playlist_plugin.c index 8adf694e..e2051943 100644 --- a/src/playlist/flac_playlist_plugin.c +++ b/src/playlist/flac_playlist_plugin.c @@ -45,7 +45,8 @@ struct flac_playlist { }; static struct playlist_provider * -flac_playlist_open_uri(const char *uri) +flac_playlist_open_uri(const char *uri, + G_GNUC_UNUSED GMutex *mutex, G_GNUC_UNUSED GCond *cond) { if (!g_path_is_absolute(uri)) /* only local files supported */ diff --git a/src/playlist/lastfm_playlist_plugin.c b/src/playlist/lastfm_playlist_plugin.c index 5c803cd9..86113643 100644 --- a/src/playlist/lastfm_playlist_plugin.c +++ b/src/playlist/lastfm_playlist_plugin.c @@ -83,15 +83,14 @@ lastfm_finish(void) * @return data fetched, or NULL on error. Must be freed with g_free. */ static char * -lastfm_get(const char *url) +lastfm_get(const char *url, GMutex *mutex, GCond *cond) { struct input_stream *input_stream; GError *error = NULL; - int ret; char buffer[4096]; size_t length = 0, nbytes; - input_stream = input_stream_open(url, &error); + input_stream = input_stream_open(url, mutex, cond, &error); if (input_stream == NULL) { if (error != NULL) { g_warning("%s", error->message); @@ -101,15 +100,9 @@ lastfm_get(const char *url) return NULL; } - while (!input_stream->ready) { - ret = input_stream_buffer(input_stream, &error); - if (ret < 0) { - input_stream_close(input_stream); - g_warning("%s", error->message); - g_error_free(error); - return NULL; - } - } + g_mutex_lock(mutex); + + input_stream_wait_ready(input_stream); do { nbytes = input_stream_read(input_stream, buffer + length, @@ -124,6 +117,7 @@ lastfm_get(const char *url) break; /* I/O error */ + g_mutex_unlock(mutex); input_stream_close(input_stream); return NULL; } @@ -131,6 +125,8 @@ lastfm_get(const char *url) length += nbytes; } while (length < sizeof(buffer)); + g_mutex_unlock(mutex); + input_stream_close(input_stream); return g_strndup(buffer, length); } @@ -162,7 +158,7 @@ lastfm_find(const char *response, const char *name) } static struct playlist_provider * -lastfm_open_uri(const char *uri) +lastfm_open_uri(const char *uri, GMutex *mutex, GCond *cond) { struct lastfm_playlist *playlist; GError *error = NULL; @@ -175,7 +171,7 @@ lastfm_open_uri(const char *uri) "username=", lastfm_config.user, "&" "passwordmd5=", lastfm_config.md5, "&" "debug=0&partner=", NULL); - response = lastfm_get(p); + response = lastfm_get(p, mutex, cond); g_free(p); if (response == NULL) return NULL; @@ -207,7 +203,7 @@ lastfm_open_uri(const char *uri) NULL); g_free(escaped_uri); - response = lastfm_get(p); + response = lastfm_get(p, mutex, cond); g_free(response); g_free(p); @@ -229,7 +225,7 @@ lastfm_open_uri(const char *uri) NULL); g_free(session); - playlist->is = input_stream_open(p, &error); + playlist->is = input_stream_open(p, mutex, cond, &error); g_free(p); if (playlist->is == NULL) { @@ -243,26 +239,17 @@ lastfm_open_uri(const char *uri) return NULL; } - while (!playlist->is->ready) { - int ret = input_stream_buffer(playlist->is, &error); - if (ret < 0) { - input_stream_close(playlist->is); - g_free(playlist); - g_warning("%s", error->message); - g_error_free(error); - return NULL; - } + g_mutex_lock(mutex); - if (ret == 0) - /* nothing was buffered - wait */ - g_usleep(10000); - } + input_stream_wait_ready(playlist->is); /* last.fm does not send a MIME type, we have to fake it here :-( */ g_free(playlist->is->mime); playlist->is->mime = g_strdup("application/xspf+xml"); + g_mutex_unlock(mutex); + /* parse the XSPF playlist */ playlist->xspf = playlist_list_open_stream(playlist->is, NULL); diff --git a/src/playlist/pls_playlist_plugin.c b/src/playlist/pls_playlist_plugin.c index 937f0279..c4e5492a 100644 --- a/src/playlist/pls_playlist_plugin.c +++ b/src/playlist/pls_playlist_plugin.c @@ -115,7 +115,8 @@ pls_open_stream(struct input_stream *is) GString *kf_data = g_string_new(""); do { - nbytes = input_stream_read(is, buffer, sizeof(buffer), &error); + nbytes = input_stream_lock_read(is, buffer, sizeof(buffer), + &error); if (nbytes == 0) { if (error != NULL) { g_string_free(kf_data, TRUE); diff --git a/src/playlist/rss_playlist_plugin.c b/src/playlist/rss_playlist_plugin.c index 9ce3c6ab..6740cba7 100644 --- a/src/playlist/rss_playlist_plugin.c +++ b/src/playlist/rss_playlist_plugin.c @@ -231,7 +231,8 @@ rss_open_stream(struct input_stream *is) &parser, rss_parser_destroy); while (true) { - nbytes = input_stream_read(is, buffer, sizeof(buffer), &error); + nbytes = input_stream_lock_read(is, buffer, sizeof(buffer), + &error); if (nbytes == 0) { if (error != NULL) { g_markup_parse_context_free(context); diff --git a/src/playlist/xspf_playlist_plugin.c b/src/playlist/xspf_playlist_plugin.c index 89a4a08a..17d9040e 100644 --- a/src/playlist/xspf_playlist_plugin.c +++ b/src/playlist/xspf_playlist_plugin.c @@ -253,7 +253,8 @@ xspf_open_stream(struct input_stream *is) &parser, xspf_parser_destroy); while (true) { - nbytes = input_stream_read(is, buffer, sizeof(buffer), &error); + nbytes = input_stream_lock_read(is, buffer, sizeof(buffer), + &error); if (nbytes == 0) { if (error != NULL) { g_markup_parse_context_free(context); -- cgit v1.2.3