]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - filter_common.c
generic_filter_pre_select(): Fix off-by-one.
[paraslash.git] / filter_common.c
index 2c74e8c702ad729928bbac1835a7f28d131e5d83..a27c2d303ad28d823ae9af20eeb4878f9300cad1 100644 (file)
@@ -6,14 +6,17 @@
 
 /** \file filter_common.c Common helper functions for filter input/output. */
 
+#include <regex.h>
 #include <sys/types.h>
 #include <dirent.h>
+#include <stdbool.h>
 
 #include "para.h"
 #include "list.h"
 #include "sched.h"
 #include "fd.h"
 #include "ggo.h"
+#include "buffer_tree.h"
 #include "filter.h"
 #include "error.h"
 #include "string.h"
@@ -43,7 +46,7 @@ void filter_init(void)
  */
 static void close_filter_callback(struct filter_callback *fcb)
 {
-       PARA_NOTICE_LOG("closing filter_callback %p, data: %p\n", fcb, fcb->data);
+       PARA_NOTICE_LOG("closing filter_callback %p\n", fcb);
        list_del(&fcb->node);
        fcb->close(fcb);
 }
@@ -105,7 +108,7 @@ static void call_callbacks(struct filter_node *fn, char *inbuf, size_t inlen,
  *
  * \sa filter_node, filter#convert, filter_callback.
  */
-void filter_pre_select(__a_unused struct sched *s, struct task *t)
+void filter_post_select(__a_unused struct sched *s, struct task *t)
 {
        struct filter_chain *fc = container_of(t, struct filter_chain, task);
        struct filter_node *fn;
@@ -142,19 +145,6 @@ again:
        conv_total += conv;
        if (conv)
                goto again;
-       if (conv_total) {
-               /*
-                * Other pre_select functions might have already been called by
-                * now and decided to do nothing, e.g. because their output
-                * buffer was full or the input buffer was empty. We just
-                * converted something which caused these buffers to change but
-                * we can't make the other tasks reconsider their decision at
-                * this point.  So force a minimal timeout for the next select
-                * call to avoid unnecessary delays.
-                */
-               s->timeout.tv_sec = 0;
-               s->timeout.tv_usec = 1;
-       }
        if (*fc->input_error >= 0)
                return;
        if (*fc->out_loaded)
@@ -285,3 +275,39 @@ void print_filter_helps(int detailed)
        }
 
 }
+
+/** 640K ought to be enough for everybody ;) */
+#define FILTER_MAX_PENDING (640 * 1024)
+
+int prepare_filter_node(struct filter_node *fn)
+{
+       struct btr_node *btrn = fn->btrn;
+       size_t iqs;
+
+       if (btr_eof(btrn))
+               return -E_FC_EOF;
+       if (btr_bytes_pending(btrn) > FILTER_MAX_PENDING)
+               return 0;
+       iqs = btr_get_input_queue_size(btrn);
+       if (iqs < fn->min_iqs && !btr_no_parent(btrn))
+               return 0;
+       assert(iqs != 0);
+       /* avoid "buffer too small" errors from the decoder */
+       btr_merge(btrn, fn->min_iqs);
+       return 1;
+}
+
+void generic_filter_pre_select(struct sched *s, struct task *t)
+{
+       struct filter_node *fn = container_of(t, struct filter_node, task);
+       size_t iqs = btr_get_input_queue_size(fn->btrn);
+
+       t->error = 0;
+       if (iqs < fn->min_iqs)
+               return;
+       if (btr_bytes_pending(fn->btrn) > FILTER_MAX_PENDING)
+               return; /* FIXME, should use reasonable bound on timeout */
+       s->timeout.tv_sec = 0;
+       s->timeout.tv_usec = 1;
+}
+