]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
stdin: Abort if the consumer terminates.
authorAndre Noll <maan@systemlinux.org>
Sun, 12 Oct 2008 22:02:35 +0000 (00:02 +0200)
committerAndre Noll <maan@systemlinux.org>
Sun, 12 Oct 2008 22:02:35 +0000 (00:02 +0200)
The bug in the wav filter which was fixed in the previous patch
could cause para_filter to hang because the stdin task would not
care whether the filter task has terminated.

Fix it by introducing an output_error pointer.

filter.c
stdin.c
stdin.h

index 09b644151a3cf4b8f081bf42743224b28a6829dd..adfadea7733d01862d1a767504e298f7d601ffa8 100644 (file)
--- a/filter.c
+++ b/filter.c
@@ -156,6 +156,7 @@ int main(int argc, char *argv[])
        ret = init_filter_chain();
        if (ret < 0)
                goto out;
        ret = init_filter_chain();
        if (ret < 0)
                goto out;
+       sit->output_error = &fc->task.error;
 
        stdout_set_defaults(sot);
        sot->buf = fc->outbuf;
 
        stdout_set_defaults(sot);
        sot->buf = fc->outbuf;
diff --git a/stdin.c b/stdin.c
index 5b6bf520cb6b09f54e6dc30cb3f21c8d7118ba63..0b84cdc72011e369bf290f671ae96d6e8cab8569 100644 (file)
--- a/stdin.c
+++ b/stdin.c
 static void stdin_pre_select(struct sched *s, struct task *t)
 {
        struct stdin_task *sit = container_of(t, struct stdin_task, task);
 static void stdin_pre_select(struct sched *s, struct task *t)
 {
        struct stdin_task *sit = container_of(t, struct stdin_task, task);
+
+       if (sit->output_error && *sit->output_error < 0) {
+               t->error = *sit->output_error;
+               return;
+       }
        t->error = 0;
        sit->check_fd = 0;
        if (sit->loaded >= sit->bufsize)
        t->error = 0;
        sit->check_fd = 0;
        if (sit->loaded >= sit->bufsize)
@@ -55,6 +60,10 @@ static void stdin_post_select(struct sched *s, struct task *t)
        struct stdin_task *sit = container_of(t, struct stdin_task, task);
        ssize_t ret;
 
        struct stdin_task *sit = container_of(t, struct stdin_task, task);
        ssize_t ret;
 
+       if (sit->output_error && *sit->output_error < 0) {
+               t->error = *sit->output_error;
+               return;
+       }
        t->error = 0;
        if (!sit->check_fd)
                return;
        t->error = 0;
        if (!sit->check_fd)
                return;
@@ -89,6 +98,7 @@ void stdin_set_defaults(struct stdin_task *sit)
        ret = mark_fd_nonblocking(STDIN_FILENO);
        if (ret >= 0)
                return;
        ret = mark_fd_nonblocking(STDIN_FILENO);
        if (ret >= 0)
                return;
+       sit->output_error = NULL;
        PARA_EMERG_LOG("%s\n", para_strerror(-ret));
        exit(EXIT_FAILURE);
 }
        PARA_EMERG_LOG("%s\n", para_strerror(-ret));
        exit(EXIT_FAILURE);
 }
diff --git a/stdin.h b/stdin.h
index 63d00d5dfc167a5c29a52ba4946bba49926d1301..99233f9ffbbd79b62035371cfed88510e36cb914 100644 (file)
--- a/stdin.h
+++ b/stdin.h
@@ -14,6 +14,8 @@ struct stdin_task {
        size_t bufsize;
        /** Number of bytes currently loaded in \a buf. */
        size_t loaded;
        size_t bufsize;
        /** Number of bytes currently loaded in \a buf. */
        size_t loaded;
+       /** Pointer to the error member of the consumer. */
+       int *output_error;
        /** Whether \p STDIN_FILENO was included in the read fd set. */
        int check_fd;
        /** The task structure. */
        /** Whether \p STDIN_FILENO was included in the read fd set. */
        int check_fd;
        /** The task structure. */