#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"
*
* \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;
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)
}
}
+
+/** 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;
+}
+