/*
- * Copyright (C) 2005-2009 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2005-2010 Andre Noll <maan@systemlinux.org>
*
* Licensed under the GPL v2. For licencing details see COPYING.
*/
struct timeval restart_barrier;
/** Last time we received status data from para_server. */
struct timeval last_status_read;
+ size_t min_iqs;
/** The offset value announced by para_server. */
int offset_seconds;
/** The length of the current audio file as announced by para_server. */
int cafn = stat_task->current_audio_format_num;
unsigned vs = stat_task->vss_status;
+ if (audiod_status != AUDIOD_ON)
+ return false;
if (cafn < 0)
return false;
if (!stat_task->ct)
para_fd_set(st->fd, &s->rfds, &s->max_fileno);
}
-static void signal_post_select(struct sched *s, struct task *t)
+static void signal_post_select(struct sched *s, __a_unused struct task *t)
{
- struct signal_task *st = container_of(t, struct signal_task, task);
-
- if (!FD_ISSET(st->fd, &s->rfds))
- return;
+ int signum;
- st->signum = para_next_signal();
- switch (st->signum) {
+ signum = para_next_signal(&s->rfds);
+ switch (signum) {
case SIGINT:
case SIGTERM:
case SIGHUP:
- PARA_EMERG_LOG("terminating on signal %d\n", st->signum);
+ PARA_EMERG_LOG("terminating on signal %d\n", signum);
clean_exit(EXIT_FAILURE, "caught deadly signal");
}
}
last_status_dump = *now;
}
- if (!FD_ISSET(ct->fd, &s->rfds))
- return;
- ret = handle_connect(ct->fd);
+ ret = handle_connect(ct->fd, &s->rfds);
if (ret < 0)
PARA_ERROR_LOG("%s\n", para_strerror(-ret));
+ audiod_status_dump();
}
static void init_command_task(struct command_task *ct)
ret = btr_node_status(st->btrn, 0, BTR_NT_LEAF);
if (ret > 0)
goto min_delay;
- if (!st->ct)
+ if (st->ct && audiod_status == AUDIOD_OFF)
+ goto min_delay;
+ if (!st->ct && audiod_status != AUDIOD_OFF)
sched_request_barrier_or_min_delay(&st->restart_barrier, s);
if (cafn >= 0)
sched_request_barrier(&afi[cafn].restart_barrier, s);
+ /*
+ * If para_server is playing we'd like to have a smooth time display
+ * even if we are running in standby mode. So we request a timeout that
+ * expires at the next full second.
+ */
+ if (stat_task->vss_status & VSS_STATUS_FLAG_PLAYING)
+ sched_request_timeout_ms(1000 - now->tv_usec / 1000, s);
return;
min_delay:
sched_min_delay(s);
}
if (st->ct->status != CL_RECEIVING)
goto out;
- ret = btr_node_status(st->btrn, 0, BTR_NT_LEAF);
- if (ret <= 0)
+ ret = btr_node_status(st->btrn, st->min_iqs, BTR_NT_LEAF);
+ if (ret <= 0) {
+ struct timeval diff;
+ tv_diff(now, &st->last_status_read, &diff);
+ if (diff.tv_sec > 61)
+ kill_btrn(st->ct->btrn, &st->ct->task,
+ -E_STATUS_TIMEOUT);
goto out;
+ }
+ btr_merge(st->btrn, st->min_iqs);
sz = btr_next_buffer(st->btrn, &buf);
ret = for_each_stat_item(buf, sz, update_item);
if (ret < 0) {
kill_btrn(st->ct->btrn, &st->ct->task, ret);
goto out;
}
- if (sz != ret)
+ if (sz != ret) {
+ btr_consume(st->btrn, sz - ret);
st->last_status_read = *now;
- else {
- struct timeval diff;
- tv_diff(now, &st->last_status_read, &diff);
- if (diff.tv_sec > 61)
- kill_btrn(st->ct->btrn, &st->ct->task,
- -E_STATUS_TIMEOUT);
- }
- btr_consume(st->btrn, sz - ret);
+ st->min_iqs = 0;
+ } else /* current status item crosses buffers */
+ st->min_iqs = sz + 1;
goto out;
}
if (tv_diff(now, &st->restart_barrier, NULL) < 0)