From 29241c4f835797f635816a9f37528aa981f722b5 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 16 Sep 2011 21:06:12 +0200 Subject: input_plugin: add method check() To check for errors without reading. The decoder thread wants to do that, before it passes the input stream to the plugin. --- src/input/curl_input_plugin.c | 18 ++++++++++++++++++ src/input/rewind_input_plugin.c | 9 +++++++++ src/input/soup_input_plugin.c | 18 ++++++++++++++++++ src/input_plugin.h | 8 ++++++++ src/input_stream.c | 10 ++++++++++ src/input_stream.h | 9 +++++++++ test/run_input.c | 6 ++++++ 7 files changed, 78 insertions(+) diff --git a/src/input/curl_input_plugin.c b/src/input/curl_input_plugin.c index 824fc9bad..4f3e9c6e4 100644 --- a/src/input/curl_input_plugin.c +++ b/src/input/curl_input_plugin.c @@ -774,6 +774,23 @@ input_curl_free(struct input_curl *c) g_free(c); } +static bool +input_curl_check(struct input_stream *is, GError **error_r) +{ + struct input_curl *c = (struct input_curl *)is; + + g_mutex_lock(c->mutex); + + bool success = c->postponed_error == NULL; + if (!success) { + g_propagate_error(error_r, c->postponed_error); + c->postponed_error = NULL; + } + + g_mutex_unlock(c->mutex); + return success; +} + static struct tag * input_curl_tag(struct input_stream *is) { @@ -1318,6 +1335,7 @@ const struct input_plugin input_plugin_curl = { .open = input_curl_open, .close = input_curl_close, + .check = input_curl_check, .tag = input_curl_tag, .buffer = input_curl_buffer, .read = input_curl_read, diff --git a/src/input/rewind_input_plugin.c b/src/input/rewind_input_plugin.c index fa2065d61..2a3eecf82 100644 --- a/src/input/rewind_input_plugin.c +++ b/src/input/rewind_input_plugin.c @@ -107,6 +107,14 @@ input_rewind_close(struct input_stream *is) g_free(r); } +static bool +input_rewind_check(struct input_stream *is, GError **error_r) +{ + struct input_rewind *r = (struct input_rewind *)is; + + return input_stream_check(r->input, error_r); +} + static void input_rewind_update(struct input_stream *is) { @@ -221,6 +229,7 @@ input_rewind_seek(struct input_stream *is, goffset offset, int whence, static const struct input_plugin rewind_input_plugin = { .close = input_rewind_close, + .check = input_rewind_check, .update = input_rewind_update, .tag = input_rewind_tag, .buffer = input_rewind_buffer, diff --git a/src/input/soup_input_plugin.c b/src/input/soup_input_plugin.c index ff73da559..23665c1a2 100644 --- a/src/input/soup_input_plugin.c +++ b/src/input/soup_input_plugin.c @@ -320,6 +320,23 @@ input_soup_close(struct input_stream *is) g_free(s); } +static bool +input_soup_check(struct input_stream *is, GError **error_r) +{ + struct input_soup *s = (struct input_soup *)is; + + g_mutex_lock(s->mutex); + + bool success = s->postponed_error == NULL; + if (!success) { + g_propagate_error(error_r, s->postponed_error); + s->postponed_error = NULL; + } + + g_mutex_unlock(s->mutex); + return success; +} + static int input_soup_buffer(struct input_stream *is, GError **error_r) { @@ -444,6 +461,7 @@ const struct input_plugin input_plugin_soup = { .open = input_soup_open, .close = input_soup_close, + .check = input_soup_check, .buffer = input_soup_buffer, .read = input_soup_read, .eof = input_soup_eof, diff --git a/src/input_plugin.h b/src/input_plugin.h index 3ac0bdf40..4e0993d12 100644 --- a/src/input_plugin.h +++ b/src/input_plugin.h @@ -51,6 +51,14 @@ struct input_plugin { struct input_stream *(*open)(const char *uri, GError **error_r); void (*close)(struct input_stream *is); + /** + * Check for errors that may have occurred in the I/O thread. + * May be unimplemented for synchronous plugins. + * + * @return false on error + */ + bool (*check)(struct input_stream *is, GError **error_r); + /** * Update the public attributes. Call before access. Can be * NULL if the plugin always keeps its attributes up to date. diff --git a/src/input_stream.c b/src/input_stream.c index 44ab7159f..164df9860 100644 --- a/src/input_stream.c +++ b/src/input_stream.c @@ -67,6 +67,16 @@ input_stream_open(const char *url, GError **error_r) return NULL; } +bool +input_stream_check(struct input_stream *is, GError **error_r) +{ + assert(is != NULL); + assert(is->plugin != NULL); + + return is->plugin->check == NULL || + is->plugin->check(is, error_r); +} + void input_stream_update(struct input_stream *is) { diff --git a/src/input_stream.h b/src/input_stream.h index 2901f6ea6..7866562ae 100644 --- a/src/input_stream.h +++ b/src/input_stream.h @@ -90,6 +90,15 @@ gcc_nonnull(1) void input_stream_close(struct input_stream *is); +/** + * Check for errors that may have occurred in the I/O thread. + * + * @return false on error + */ +gcc_nonnull(1) +bool +input_stream_check(struct input_stream *is, GError **error_r); + /** * Update the public attributes. Call before accessing attributes * such as "ready" or "offset". diff --git a/test/run_input.c b/test/run_input.c index c00698dff..651d36480 100644 --- a/test/run_input.c +++ b/test/run_input.c @@ -100,6 +100,12 @@ dump_input_stream(struct input_stream *is) break; } + if (!input_stream_check(is, &error)) { + g_warning("%s", error->message); + g_error_free(error); + return EXIT_FAILURE; + } + return 0; } -- cgit v1.2.3