* para_audiod uses \p MAX_STREAM_SLOTS different slots, each of which may
* be associated with a receiver/filter/writer triple. This array holds all
* information on the status of these slots.
- *
- * \sa struct slot_info
- * */
+ */
struct slot_info slot[MAX_STREAM_SLOTS];
/** The vss status flags audiod is interested in. */
char *stat_item_values[NUM_STAT_ITEMS] = {NULL};
/**
- * the current mode of operation of which can be changed by the on/off/cycle
- * commands. It is either, AUDIOD_OFF, AUDIOD_ON or AUDIOD_STANDBY.
+ * The current mode of operation (AUDIOD_OFF, AUDIOD_ON or AUDIOD_STANDBY).
+ * Set by the on/off/cycle commands.
*/
int audiod_status = AUDIOD_ON;
static uid_t *uid_whitelist;
/**
- * the task that calls the status command of para_server
+ * The task that calls the status command of para_server.
*
- * \sa struct status_task
+ * \sa \ref struct status_task.
*/
static struct status_task *stat_task = &status_task_struct;
-/*
- * The task for handling audiod commands.
- *
- * We need two listening sockets for backward compability: on Linux systems
- * fd[0] is an abstract socket (more precisely, a socket bound to an address in
- * the abstract namespace), and fd[1] is the usual pathname socket. On other
- * systems, fd[0] is negative, and only the pathname socket is used.
- *
- * For 0.5.x we accept connections on both sockets to make sure that old
- * para_audioc versions can still connect. New versions use only the abstract
- * socket. Hence after v0.6.0 we can go back to a single socket, either an
- * abstract one (Linux) or a pathname socket (all other systems).
- */
struct command_task {
- /** The local listening sockets. */
- int fd[2];
- /** the associated task structure */
+ /** The local listening socket. */
+ int fd;
+ /** The associated task structure. */
struct task *task;
};
-/** iterate over all supported audio formats */
+/** Iterate over all supported audio formats. */
#define FOR_EACH_AUDIO_FORMAT(af) for (af = 0; af < NUM_AUDIO_FORMATS; af++)
/**
rskip; /* receiver start - sss */
int slot_num = get_play_time_slot_num();
struct slot_info *s = slot_num < 0? NULL : &slot[slot_num];
+ bool writer_active = s && s->wns && s->wns[0].btrn;
char *msg;
if (audiod_status == AUDIOD_OFF)
}
/*
* Valid status items and playing, set length and tmp to the stream
- * start. We use the slot info and fall back to the info from current
- * status items if no slot info is available.
+ * start. We use the writer start time from the slot info and fall back
+ * to the info from current status items if no writer is active yet.
*/
tmp = &stat_task->server_stream_start;
- if (s && s->wns && s->wns[0].btrn) { /* writer active in this slot */
+ if (writer_active) {
btr_get_node_start(s->wns[0].btrn, &wstime);
if (wstime.tv_sec != 0) { /* writer wrote something */
if (s->server_stream_start.tv_sec == 0) {
tv_diff(tmp, &stat_task->sa_time_diff, &sss);
else
tv_add(tmp, &stat_task->sa_time_diff, &sss);
- if (!s || !s->wns || !s->wns[0].btrn || wstime.tv_sec == 0) {
+ if (!writer_active) {
struct timeval diff;
tv_diff(now, &sss, &diff);
seconds = diff.tv_sec + stat_task->offset_seconds;
}
/* add "dec" to audio format name */
tmp = make_message("%sdec", audio_formats[i]);
- for (j = 0; filter_get(j); j++)
+ for (j = 1; filter_get(j); j++)
if (!strcmp(tmp, filter_name(j)))
break;
free(tmp);
}
/* does not unlink socket on errors */
-static void init_local_sockets(struct command_task *ct)
+static void init_local_socket(struct command_task *ct)
{
if (OPT_GIVEN(SOCKET))
socket_name = para_strdup(OPT_STRING_VAL(SOCKET));
PARA_NOTICE_LOG("local socket: %s\n", socket_name);
if (OPT_GIVEN(FORCE))
unlink(socket_name);
- ct->fd[0] = create_local_socket(socket_name, 0);
- ct->fd[1] = create_local_socket(socket_name,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
- if (ct->fd[0] >= 0 || ct->fd[1] >= 0)
+ ct->fd = create_local_socket(socket_name);
+ if (ct->fd >= 0)
return;
- PARA_EMERG_LOG("%s\n", para_strerror(-ct->fd[1]));
+ PARA_EMERG_LOG("%s\n", para_strerror(-ct->fd));
exit(EXIT_FAILURE);
}
static void command_pre_select(struct sched *s, void *context)
{
struct command_task *ct = context;
- int i;
-
- for (i = 0; i < 2; i++)
- if (ct->fd[i] >= 0)
- para_fd_set(ct->fd[i], &s->rfds, &s->max_fileno);
+ para_fd_set(ct->fd, &s->rfds, &s->max_fileno);
}
static int command_post_select(struct sched *s, void *context)
{
- int ret, i;
+ int ret;
struct command_task *ct = context;
static struct timeval last_status_dump;
struct timeval tmp, delay;
ret = task_get_notification(ct->task);
if (ret < 0)
return ret;
- for (i = 0; i < 2; i++) {
- if (ct->fd[i] < 0)
- continue;
- ret = handle_connect(ct->fd[i], &s->rfds);
- if (ret < 0) {
- PARA_ERROR_LOG("%s\n", para_strerror(-ret));
- if (ret == -E_AUDIOD_TERM) {
- task_notify_all(s, -ret);
- return ret;
- }
- } else if (ret > 0)
- force = true;
- }
+ ret = handle_connect(ct->fd, &s->rfds);
+ if (ret < 0) {
+ PARA_ERROR_LOG("%s\n", para_strerror(-ret));
+ if (ret == -E_AUDIOD_TERM) {
+ task_notify_all(s, -ret);
+ return ret;
+ }
+ } else if (ret > 0)
+ force = true;
if (force == true)
goto dump;
static void init_command_task(struct command_task *ct)
{
- init_local_sockets(ct); /* doesn't return on errors */
+ init_local_socket(ct); /* doesn't return on errors */
ct->task = task_register(&(struct task_info) {
.name = "command",