]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - audiod.c
audiod: switch from ringbuffer to statically allocated array
[paraslash.git] / audiod.c
index cd43f24f47fa31beb27184a39f6dcd560fe3fb3e..c9a0ff7f02dd9595b984abfd10f46a59085a9cc4 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -28,7 +28,6 @@
 #include "filter.h"
 #include "grab_client.cmdline.h"
 #include "grab_client.h"
-#include "ringbuffer.h"
 
 #include "error.h"
 #include "audiod.h"
@@ -131,23 +130,11 @@ static int playing, current_decoder = -1,
        sa_time_diff_sign = 1, audiod_socket = -1;
 static char *af_status, /* the audio format announced in server status */
        *socket_name, *hostname;
-/** how many status items to remember */
-#define RINGBUFFER_SIZE 32
-static void *stat_item_ringbuf;
+static char *stat_item_values[NUM_STAT_ITEMS];
 static FILE *logfile;
 static const struct timeval restart_delay = {0, 300 * 1000};
 
-static struct audio_format_info afi[] = {
-
-[AUDIO_FORMAT_MP3] =
-       {
-               .write_cmd = "para_play",
-       },
-[AUDIO_FORMAT_OGG] =
-       {
-               .write_cmd = "para_play",
-       },
-};
+static struct audio_format_info afi[NUM_AUDIO_FORMATS];
 
 static struct audiod_command cmds[] = {
 {
@@ -269,7 +256,7 @@ int get_audio_format_num(char *name)
 /*
  * log function. first argument is loglevel.
  */
-void para_log(int ll, char* fmt,...)
+void para_log(int ll, const char* fmt,...)
 {
        va_list argp;
        FILE *outfd;
@@ -312,9 +299,11 @@ static char *get_time_string(struct timeval *newest_stime)
        struct timeval now, diff, adj_stream_start, tmp;
        int total = 0, use_server_time = 1;
 
-       if (!playing)
-               return make_message("%s:", length_seconds?
-                       "" : status_item_list[SI_PLAY_TIME]);
+       if (!playing) {
+               if (length_seconds)
+                       return NULL;
+               return make_message("%s:", status_item_list[SI_PLAY_TIME]);
+       }
        if (audiod_status == AUDIOD_OFF)
                goto out;
        if (sa_time_diff_sign > 0)
@@ -380,12 +369,13 @@ static char *audiod_status_string(void)
        decoder_flags[MAX_STREAM_SLOTS] = '\0';
        time_string = get_time_string(newest_stime);
        uptime_string = uptime_str();
-       ret = make_message("%s:%s\n%s:%s\n%s:%s\n%s",
+       ret = make_message("%s:%s\n%s:%s\n%s:%s",
                status_item_list[SI_AUDIOD_UPTIME], uptime_string,
                status_item_list[SI_DECODER_FLAGS], decoder_flags,
                status_item_list[SI_AUDIOD_STATUS], audiod_status == AUDIOD_ON?
-                       "on" : (audiod_status == AUDIOD_OFF? "off": "sb"),
-               time_string);
+                       "on" : (audiod_status == AUDIOD_OFF? "off": "sb"));
+       if (time_string)
+               ret = make_message("%s\n%s", ret, time_string);
        free(uptime_string);
        free(decoder_flags);
        free(time_string);
@@ -448,11 +438,21 @@ static void kill_stream_writer(int slot_num)
        s->fci->error = 1;
 }
 
+static void set_restart_barrier(int format, struct timeval *now)
+{
+       struct timeval tmp;
+
+       if (now)
+               tmp = *now;
+       else
+               gettimeofday(&tmp, NULL);
+       tv_add(&tmp, &restart_delay, &afi[format].restart_barrier);
+}
+
 static void close_receiver(int slot_num)
 {
        struct slot_info *s = &slot[slot_num];
        struct audio_format_info *a;
-       struct timeval now;
 
        if (s->format < 0 || !s->receiver_node)
                return;
@@ -462,8 +462,7 @@ static void close_receiver(int slot_num)
        a->receiver->close(s->receiver_node);
        free(s->receiver_node);
        s->receiver_node = NULL;
-       gettimeofday(&now, NULL);
-       tv_add(&now, &restart_delay, &a->restart_barrier); /* FIXME: Use set_restart_barrier() */
+       set_restart_barrier(s->format, NULL);
 }
 
 static void kill_all_decoders(void)
@@ -477,17 +476,6 @@ static void kill_all_decoders(void)
                }
 }
 
-static void set_restart_barrier(int format, struct timeval *now)
-{
-       struct timeval tmp;
-
-       if (now)
-               tmp = *now;
-       else
-               gettimeofday(&tmp, NULL);
-       tv_add(&tmp, &restart_delay, &afi[format].restart_barrier);
-}
-
 static void check_sigchld(void)
 {
        pid_t pid;
@@ -558,7 +546,6 @@ static int decoder_running(int format)
 
 static void close_stat_pipe(void)
 {
-       char *msg;
        int i;
 
        if (stat_pipe < 0)
@@ -568,17 +555,18 @@ static void close_stat_pipe(void)
        del_close_on_fork_list(stat_pipe);
        stat_pipe = -1;
        kill_all_decoders();
-       for (i = 0; i < RINGBUFFER_SIZE; i++)
-               free(ringbuffer_add(stat_item_ringbuf, para_strdup(NULL)));
+       for (i = 0; i < NUM_STAT_ITEMS; i++) {
+               free(stat_item_values[i]);
+               stat_item_values[i] = NULL;
+       }
        dump_empty_status();
        length_seconds = 0;
        offset_seconds = 0;
        audiod_status_dump();
        playing = 0;
-       msg = make_message("%s:no connection to para_server\n",
+       stat_item_values[SI_STATUS_BAR] = make_message("%s:no connection to para_server\n",
                status_item_list[SI_STATUS_BAR]);
-       free(ringbuffer_add(stat_item_ringbuf, msg));
-       stat_client_write(msg);
+       stat_client_write(stat_item_values[SI_STATUS_BAR]);
 }
 
 static void __noreturn clean_exit(int status, const char *msg)
@@ -592,7 +580,7 @@ static void __noreturn clean_exit(int status, const char *msg)
        exit(status);
 }
 
-static char *glob_cmd(char *cmd)
+__malloc static char *glob_cmd(char *cmd)
 {
        char *ret, *replacement;
        struct timeval tmp, delay, rss; /* real stream start */
@@ -690,12 +678,15 @@ static void start_stream_writer(int slot_num)
        int ret, fds[3] = {1, -1, -1};
        struct slot_info *s = &slot[slot_num];
        struct audio_format_info *a = &afi[s->format];
-       char *glob = glob_cmd(a->write_cmd);
+       char *glob = NULL;
 
-       PARA_INFO_LOG("starting stream writer: %s\n", glob? glob : a->write_cmd);
+       if (a->write_cmd)
+               glob = glob_cmd(a->write_cmd);
+       if (!glob)
+               glob = para_strdup("para_play");
+       PARA_INFO_LOG("starting stream writer: %s\n", glob);
        open_filters(slot_num);
-
-       ret = para_exec_cmdline_pid(&s->wpid, glob? glob : a->write_cmd, fds);
+       ret = para_exec_cmdline_pid(&s->wpid, glob, fds);
        free(glob);
        if (ret < 0) {
                PARA_ERROR_LOG("exec failed (%d)\n", ret);
@@ -805,11 +796,14 @@ static void check_stat_line(char *line)
 
        if (!line)
                return;
-       free(ringbuffer_add(stat_item_ringbuf, para_strdup(line)));
-       stat_client_write(line);
        itemnum = stat_line_valid(line);
-       if (itemnum < 0)
+       if (itemnum < 0) {
+               PARA_WARNING_LOG("invalid status line: %s\n", line);
                return;
+       }
+       stat_client_write(line);
+       free(stat_item_values[itemnum]);
+       stat_item_values[itemnum] = para_strdup(line);
        ilen = strlen(status_item_list[itemnum]);
        switch (itemnum) {
        case SI_STATUS:
@@ -1086,7 +1080,7 @@ static int setup_default_filters(void)
                if (ret < 0)
                        goto out;
                PARA_INFO_LOG("%s -> default filter: %s\n", audio_formats[i], filters[j].name);
-               ret = add_filter(i, "wav");
+               ret = add_filter(i, para_strdup("wav"));
                if (ret < 0)
                        goto out;
                PARA_INFO_LOG("%s -> default filter: wav\n", audio_formats[i]);
@@ -1192,7 +1186,7 @@ static int dump_commands(int fd)
 /*
  * command handlers don't close their fd on errors (ret < 0) so that
  * its caller can send an error message. Otherwise (ret >= 0) it's up
- * to each individual command to close the fd if necessary.  
+ * to each individual command to close the fd if necessary.
  */
 
 static int com_help(int fd, int argc, char **argv)
@@ -1233,16 +1227,13 @@ out:
 static int com_stat(int fd, __unused int argc, __unused char **argv)
 {
        int i, ret;
-       char *buf = audiod_status_string();
+       char *buf = make_message("%s\n", audiod_status_string());
 
-       buf = para_strcat(buf, "\n");
-       for (i = RINGBUFFER_SIZE - 1; i >= 0; i--) {
-               char *tmp, *line = ringbuffer_get(stat_item_ringbuf, i);
-               if (!line)
-                       continue;
-               tmp = make_message("%s\n", line);
-               buf = para_strcat(buf, tmp);
-               free(tmp);
+       for (i = 0; i < NUM_STAT_ITEMS; i++) {
+               char *tmp, *v = stat_item_values[i];
+               tmp = make_message("%s%s%s", buf, v? v : "", v? "\n" : "");
+               free(buf);
+               buf = tmp;
        }
        ret = client_write(fd, buf);
        if (ret > 0)
@@ -1429,9 +1420,8 @@ static void audiod_get_socket(void)
 static int open_stat_pipe(void)
 {
        int ret, fd[3] = {-1, 1, 0};
-       char *argv[] = {BINDIR "/para_client", "stat", NULL};
        pid_t pid;
-       ret = para_exec(&pid, BINDIR "/para_client",  argv, fd);
+       ret = para_exec_cmdline_pid(&pid, BINDIR "/para_client stat", fd);
        if (ret >= 0) {
                ret = fd[1];
                PARA_NOTICE_LOG("stat pipe opened, fd %d\n", ret);
@@ -1607,7 +1597,6 @@ int __noreturn main(int argc, char *argv[])
        set_initial_status();
        FOR_EACH_SLOT(i)
                clear_slot(i);
-       stat_item_ringbuf = ringbuffer_new(RINGBUFFER_SIZE);
        init_grabbing();
        setup_signal_handling();
        if (conf.daemon_given)