register_task(&rn->task);
}
-static int is_frozen(int format)
-{
- struct audio_format_info *a = &afi[format];
-
- return (tv_diff(now, &a->restart_barrier, NULL) > 0)? 0 : 1;
-}
-
-static void open_current_receiver(struct sched *s)
+static int open_current_receiver(struct sched *s)
{
int i;
+ struct timeval diff;
if (!af_status)
- return;
+ return 0;
i = get_audio_format_num(af_status);
if (i < 0)
- return;
- if (decoder_running(i) || is_frozen(i))
- return;
+ return 0;
+ if (decoder_running(i))
+ return 0;
+ if (tv_diff(now, &afi[i].restart_barrier, &diff) < 0) {
+ s->timeout = diff;
+ return 0;
+ }
open_receiver(i);
- /*
- * the receiver didn't get a chance to put his fd to the fd set.
- * Make the upcoming select() return immediately to avoid a long
- * timeout.
- */
- s->timeout.tv_sec = 0;
- s->timeout.tv_usec = 1;
+ return 1;
}
static void compute_time_diff(const struct timeval *status_time)
clear_slot(slot_num);
}
+/*
+ * Check if any receivers/filters/writers need to be started and do so if
+ * neccessary. Since the pre_select function didn't have a chance yet to put
+ * file descriptors into the fd sets given by s, make the upcoming select()
+ * return immediately to avoid a long timeout in case we started something.
+ */
static void audiod_pre_select(struct sched *s, __a_unused struct task *t)
{
int i;
+ struct timeval min_delay = {0, 1};
t->ret = 1;
now = &s->now;
if (audiod_status != AUDIOD_ON || !playing)
- kill_all_decoders();
- else if (playing)
- open_current_receiver(s);
+ return kill_all_decoders();
+ if (open_current_receiver(s))
+ s->timeout = min_delay;
FOR_EACH_SLOT(i) {
- struct slot_info *s = &slot[i];
+ struct slot_info *sl = &slot[i];
struct audio_format_info *a;
- if (s->format < 0)
+ if (sl->format < 0)
continue;
- a = &afi[s->format];
- if (!s->receiver_node)
+ a = &afi[sl->format];
+ if (!sl->receiver_node)
continue;
if (!a->num_filters) {
- if (s->receiver_node->loaded && !s->wng)
+ if (sl->receiver_node->loaded && !sl->wng) {
open_writers(i);
+ s->timeout = min_delay;
+ }
continue;
}
- if (s->receiver_node->loaded && !s->fc) {
+ if (sl->receiver_node->loaded && !sl->fc) {
open_filters(i);
+ s->timeout = min_delay;
continue;
}
- if (s->fc && *s->fc->out_loaded && !s->wng)
+ if (sl->fc && *sl->fc->out_loaded && !sl->wng) {
open_writers(i);
+ s->timeout = min_delay;
+ }
}
}