X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=audiod.c;h=741bd68b0344c510ecdd750e897aedfa25b9ee48;hb=513a3be6c609dd812e2b7755bab533d28676bd9c;hp=9e001c67ee73562f453a69f13e5a644d04e55169;hpb=adbf9f09c9bf2a680c61b1ef3541c04f1cde97cf;p=paraslash.git diff --git a/audiod.c b/audiod.c index 9e001c67..741bd68b 100644 --- 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,9 +130,7 @@ 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}; @@ -211,11 +208,10 @@ GRAB_HELP_TXT .name = "stat", .handler = com_stat, .description = "print status information", -.synopsis = "stat", +.synopsis = "stat [item1 ...]", .help = -"Add para_audiod status information to para_server's status information\n" -"and dump everything to stdout.\n" +"Dump given status items (all if none given) to stdout.\n" }, { @@ -302,9 +298,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:\n", status_item_list[SI_PLAY_TIME]); + } if (audiod_status == AUDIOD_OFF) goto out; if (sa_time_diff_sign > 0) @@ -330,7 +328,7 @@ static char *get_time_string(struct timeval *newest_stime) total = 0; out: return make_message( - "%s:%s%d:%02d [%d:%02d] (%d%%/%d:%02d)", + "%s:%s%d:%02d [%d:%02d] (%d%%/%d:%02d)\n", status_item_list[SI_PLAY_TIME], use_server_time? "~" : "", total / 60, @@ -344,12 +342,31 @@ out: ); } -static char *audiod_status_string(void) +__malloc static char *audiod_status_string(void) +{ + const char *status = (audiod_status == AUDIOD_ON)? + "on" : (audiod_status == AUDIOD_OFF)? "off": "sb"; + return make_message("%s:%s\n", status_item_list[SI_AUDIOD_STATUS], status); +} + +static struct timeval *wstime(void) { int i; - struct timeval *newest_stime = NULL; - char *ret, *time_string, *uptime_string, *decoder_flags = - para_malloc((MAX_STREAM_SLOTS + 1) * sizeof(char)); + struct timeval *max = NULL; + FOR_EACH_SLOT(i) { + struct slot_info *s = &slot[i]; + if (s->wpid <= 0) + continue; + if (max && tv_diff(&s->wstime, max, NULL) <= 0) + continue; + max = &s->wstime; + } + return max; +} +__malloc static char *decoder_flags(void) +{ + int i; + char decoder_flags[MAX_STREAM_SLOTS + 1]; FOR_EACH_SLOT(i) { struct slot_info *s = &slot[i]; @@ -361,25 +378,10 @@ static char *audiod_status_string(void) if (flag != '0') flag += s->format * 4; decoder_flags[i] = flag; - if (s->wpid <= 0) - continue; - if (newest_stime && tv_diff(&s->wstime, newest_stime, NULL) <= 0) - continue; - newest_stime = &s->wstime; } 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", - 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); - free(uptime_string); - free(decoder_flags); - free(time_string); - return ret; + return make_message("%s:%s\n", status_item_list[SI_DECODER_FLAGS], + decoder_flags); } static char *configfile_exists(void) @@ -407,13 +409,34 @@ static void setup_signal_handling(void) static void audiod_status_dump(void) { - static char *prev_status; - char *tmp = audiod_status_string(); - - if (!prev_status || strcmp(tmp, prev_status)) - stat_client_write(tmp); - free(prev_status); - prev_status = tmp; + static char *p_ts, *p_us, *p_as, *p_df; + struct timeval *t = wstime(); + char *us, *tmp = get_time_string(t); + + if (tmp && (!p_ts || strcmp(tmp, p_ts))) + stat_client_write(tmp, SI_PLAY_TIME); + free(p_ts); + p_ts = tmp; + + us = uptime_str(); + tmp = make_message("%s:%s\n", status_item_list[SI_AUDIOD_UPTIME], us); + free(us); + if (!p_us || strcmp(p_us, tmp)) + stat_client_write(tmp, SI_AUDIOD_UPTIME); + free(p_us); + p_us = tmp; + + tmp = audiod_status_string(); + if (!p_as || strcmp(p_as, tmp)) + stat_client_write(tmp, SI_AUDIOD_STATUS); + free(p_as); + p_as = tmp; + + tmp = decoder_flags(); + if (!p_df || strcmp(p_df, tmp)) + stat_client_write(tmp, SI_DECODER_FLAGS); + free(p_df); + p_df = tmp; } static void clear_slot(int slot_num) @@ -546,7 +569,6 @@ static int decoder_running(int format) static void close_stat_pipe(void) { - char *msg; int i; if (stat_pipe < 0) @@ -556,17 +578,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], SI_STATUS_BAR); } static void __noreturn clean_exit(int status, const char *msg) @@ -793,14 +816,20 @@ static void check_stat_line(char *line) int itemnum; size_t ilen = 0; struct timeval tv; + char *tmp; 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; + } + tmp = make_message("%s\n", line); + stat_client_write(tmp, itemnum); + free(tmp); + free(stat_item_values[itemnum]); + stat_item_values[itemnum] = para_strdup(line); ilen = strlen(status_item_list[itemnum]); switch (itemnum) { case SI_STATUS: @@ -1183,7 +1212,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) @@ -1224,20 +1253,68 @@ out: static int com_stat(int fd, __unused int argc, __unused char **argv) { int i, ret; - char *buf = audiod_status_string(); + char *buf = NULL; + long unsigned mask = ~0LU; - 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); + if (argc > 1) { + mask = 0; + for (i = 1; i < argc; i++) { + ret = stat_item_valid(argv[i]); + if (ret < 0) + return ret; + mask |= (1 << ret); + } + } + PARA_INFO_LOG("mask: 0x%lx\n", mask); + if (mask & (1 << SI_PLAY_TIME)) { + struct timeval *t = wstime(); + char *ts = get_time_string(t); + if (ts) { + ret = client_write(fd, ts); + if (ret < 0) + goto out; + free(ts); + } + } + if (mask & (1 << SI_AUDIOD_UPTIME)) { + char *tmp, *us = uptime_str(); + tmp = make_message("%s:%s\n", + status_item_list[SI_AUDIOD_UPTIME], us); + free(us); + ret = client_write(fd, tmp); + if (ret < 0) + goto out; free(tmp); } + if (mask & (1 << SI_AUDIOD_STATUS)) { + char *s = audiod_status_string(); + ret = client_write(fd, s); + if (ret < 0) + goto out; + free(s); + } + if (mask & (1 << SI_DECODER_FLAGS)) { + char *df =decoder_flags(); + ret = client_write(fd, df); + if (ret < 0) + goto out; + free(df); + } + + for (i = 0; i < NUM_STAT_ITEMS; i++) { + char *tmp, *v; + if (!((1 << i) & mask)) + continue; + v = stat_item_values[i]; + tmp = make_message("%s%s%s", buf? buf: "", + v? v : "", v? "\n" : ""); + free(buf); + buf = tmp; + } ret = client_write(fd, buf); +out: if (ret > 0) - ret = stat_client_add(fd); + ret = stat_client_add(fd, mask); free(buf); return ret; } @@ -1597,7 +1674,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)