X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=audiod.c;h=8f6f3560ee37cb6cbb927630bb583937d51693db;hp=c93a05fe275186ec2b1275c770ec95f239041350;hb=8cec3d1edb26b4861e2b5bdbb9f70241cdd7f03b;hpb=86733a1bedc2e9358c9ac06ff8368217de3243e3;ds=sidebyside diff --git a/audiod.c b/audiod.c index c93a05fe..8f6f3560 100644 --- a/audiod.c +++ b/audiod.c @@ -18,7 +18,6 @@ /** \file audiod.c the paraslash's audio daemon */ -#include /* gettimeofday */ #include "para.h" #include "audiod.cmdline.h" @@ -84,10 +83,6 @@ struct audio_format_info { struct slot_info { /** number of the audio format in this slot */ int format; - /** time of the last successful read from the receiver */ - struct timeval rtime; - /** time the last write to the write fd happend */ - struct timeval wtime; /** writer start time */ struct timeval wstime; /** the receiver info associated with this slot */ @@ -111,29 +106,39 @@ static char *af_status, /* the audio format announced in server status */ 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[NUM_AUDIO_FORMATS]; +static struct timeval *now; static struct signal_task signal_task_struct, *sig_task = &signal_task_struct; +/** + * the task for handling audiod commands + * + * \sa struct task, struct sched + */ struct command_task { + /** the local listening socket */ int fd; + /** the associated task structure */ struct task task; }; -static struct command_task command_task_struct, *cmd_task = &command_task_struct; +/** + * the task for audiod's child (para_client stat) + * + * \sa struct task, struct sched + */ struct status_task { + /** the output of the stat command is read from this fd */ int fd; - struct task task; + /** stat data is stored here */ char buf[STRINGSIZE]; + /** number of bytes loaded in \a buf */ unsigned loaded; -}; -static struct status_task status_task_struct, *stat_task = &status_task_struct; - -struct audiod_task { + /** the associated task structure */ struct task task; }; -static struct audiod_task audiod_task_struct, *at = &audiod_task_struct; +static struct status_task status_task_struct, *stat_task = &status_task_struct; struct signal_task { int fd; @@ -141,13 +146,17 @@ struct signal_task { struct task task; }; - /** defines one command of para_audiod */ struct audiod_command { /** the name of the command */ const char *name; /** pointer to the function that handles the command */ int (*handler)(int, int, char**); + /** + * if the command prefers to handle the full line (rather than the usual + * argv[] array), it stores a pointer to the corresponding line handling + * function here. In this case, the above \a handler pointer must be NULL. + */ int (*line_handler)(int, char*); /** one-line description of the command */ const char *description; @@ -315,7 +324,7 @@ static int client_write(int fd, const char *buf) static char *get_time_string(struct timeval *newest_stime) { - struct timeval now, diff, adj_stream_start, tmp; + struct timeval diff, adj_stream_start, tmp; int total = 0, use_server_time = 1; if (!playing) { @@ -339,8 +348,7 @@ static char *get_time_string(struct timeval *newest_stime) use_server_time = 0; } } - gettimeofday(&now, NULL); - tv_diff(&now, &tmp, &diff); + tv_diff(now, &tmp, &diff); total = diff.tv_sec + offset_seconds; if (total > length_seconds) total = length_seconds; @@ -466,17 +474,6 @@ static void clear_slot(int slot_num) s->format = -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]; @@ -485,49 +482,40 @@ static void close_receiver(int slot_num) if (s->format < 0 || !s->receiver_node) return; a = &afi[s->format]; - PARA_NOTICE_LOG("closing %s recevier in slot %d (eof = %d)\n", + PARA_NOTICE_LOG("closing %s receiver in slot %d (eof = %d)\n", audio_formats[s->format] , slot_num, s->receiver_node->eof); if (!s->receiver_node->eof) unregister_task(&s->receiver_node->task); a->receiver->close(s->receiver_node); free(s->receiver_node); s->receiver_node = NULL; - set_restart_barrier(s->format, NULL); -} -static void close_writer(int slot_num) -{ - struct slot_info *s = &slot[slot_num]; - if (s->wng) { - PARA_INFO_LOG("slot %d: closing writer node group\n", - slot_num); - wng_close(s->wng); - s->wng = NULL; - } - if (s->fc) - *s->fc->output_eof = 1; /* FIXME */ + /* set restart barrier */ + tv_add(now, &restart_delay, &afi[s->format].restart_barrier); } - static void kill_all_decoders(void) { int i; - FOR_EACH_SLOT(i) - close_writer(i); -} - -static void check_sigchld(void) -{ - pid_t pid; - struct timeval now; - gettimeofday(&now, NULL); - -reap_next_child: - pid = para_reap_child(); - if (pid <= 0) - return; - PARA_CRIT_LOG("para_client died (pid %d)\n", pid); - goto reap_next_child; + FOR_EACH_SLOT(i) { + struct slot_info *s = &slot[i]; + if (s->wng && !s->wng->eof) { + PARA_INFO_LOG("unregistering writer node group in slot %d\n", + i); + wng_unregister(s->wng); + s->wng->eof = 1; + } + if (s->fc && !s->fc->eof) { + PARA_INFO_LOG("unregistering filter chain in slot %d\n", i); + unregister_task(&s->fc->task); + s->fc->eof = 1; + } + if (s->receiver_node && !s->receiver_node->eof) { + PARA_INFO_LOG("unregistering receiver_node in slot %d\n", i); + unregister_task(&s->receiver_node->task); + s->receiver_node->eof = 1; + } + } } static int get_empty_slot(void) @@ -541,11 +529,7 @@ static int get_empty_slot(void) clear_slot(i); return i; } - if (s->wng) - continue; - if (s->receiver_node) - continue; - if (s->fc) + if (s->wng || s->receiver_node || s->fc) continue; clear_slot(i); return i; @@ -588,7 +572,8 @@ static void close_stat_pipe(void) offset_seconds = 0; audiod_status_dump(); playing = 0; - stat_item_values[SI_STATUS_BAR] = 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]); stat_client_write(stat_item_values[SI_STATUS_BAR], SI_STATUS_BAR); } @@ -596,7 +581,6 @@ static void close_stat_pipe(void) static void __noreturn clean_exit(int status, const char *msg) { PARA_EMERG_LOG("%s\n", msg); - kill_all_decoders(); if (socket_name) unlink(socket_name); if (stat_task->fd >= 0) @@ -604,13 +588,21 @@ static void __noreturn clean_exit(int status, const char *msg) exit(status); } -/** get the number of filters for the given audio format */ +/** + * get the number of filters + * + * \param audio_format_num the number identifying the audio format + * + * \return the number of filters for the given audio format + * + * \sa struct filter; + */ int num_filters(int audio_format_num) { return afi[audio_format_num].num_filters; } -void filter_event_handler(struct task *t) +static void filter_event_handler(struct task *t) { PARA_NOTICE_LOG("%s\n", PARA_STRERROR(-t->ret)); unregister_task(t); @@ -626,17 +618,19 @@ static void open_filters(int slot_num) s->fc = NULL; if (!nf) return; + PARA_INFO_LOG("opening %s filters\n", audio_formats[s->format]); s->fc = para_calloc(sizeof(struct filter_chain)); INIT_LIST_HEAD(&s->fc->filters); s->fc->inbuf = s->receiver_node->buf; s->fc->in_loaded = &s->receiver_node->loaded; s->fc->input_eof = &s->receiver_node->eof; - s->fc->task.pre_select = filter_pre_select; s->fc->task.event_handler = filter_event_handler; s->fc->task.private_data = s->fc; s->fc->task.flags = 0; s->fc->eof = 0; + + s->receiver_node->output_eof = &s->fc->eof; sprintf(s->fc->task.status, "filter chain"); for (i = 0; i < nf; i++) { struct filter_node *fn = para_calloc(sizeof(struct filter_node)); @@ -653,8 +647,6 @@ static void open_filters(int slot_num) s->fc->out_loaded = &fn->loaded; } register_task(&s->fc->task); -// PARA_DEBUG_LOG("output loaded for filter chain %p: %p\n", s->fc, -// s->fc->out_loaded); } static struct filter_node *find_filter_node(int slot_num, int format, int filternum) @@ -684,28 +676,24 @@ static struct filter_node *find_filter_node(int slot_num, int format, int filter static void wng_event_handler(struct task *t) { - struct writer_node_group *g = t->private_data; + struct writer_node_group *wng = t->private_data; int i; - PARA_INFO_LOG("%s\n", PARA_STRERROR(-t->ret)); - unregister_task(t); + wng_unregister(wng); FOR_EACH_SLOT(i) { - if (slot[i].wng != g) + struct slot_info *s = &slot[i]; + if (s->wng != wng) continue; - wng_close(g); - wng_destroy(g); - slot[i].wng = NULL; + PARA_INFO_LOG("slot %d: %s\n", i, PARA_STRERROR(-t->ret)); } } -static void start_stream_writer(int slot_num, struct timeval *now) +static void open_writers(int slot_num) { int ret, i; struct slot_info *s = &slot[slot_num]; struct audio_format_info *a = &afi[s->format]; - PARA_INFO_LOG("opening %s filters\n", audio_formats[s->format]); - open_filters(slot_num); PARA_INFO_LOG("opening %s writers\n", audio_formats[s->format]); if (!a->num_writers) s->wng = setup_default_wng(); @@ -715,7 +703,10 @@ static void start_stream_writer(int slot_num, struct timeval *now) s->wng->buf = s->fc->outbuf; s->wng->loaded = s->fc->out_loaded; s->wng->input_eof = &s->fc->eof; + s->wng->channels = &s->fc->channels; + s->wng->samplerate = &s->fc->samplerate; s->fc->output_eof = &s->wng->eof; + PARA_INFO_LOG("samplerate: %d\n", *s->wng->samplerate); } else { s->wng->buf = s->receiver_node->buf; s->wng->loaded = &s->receiver_node->loaded; @@ -725,20 +716,21 @@ static void start_stream_writer(int slot_num, struct timeval *now) for (i = 0; i < a->num_writers; i++) { s->wng->writer_nodes[i].conf = a->writer_conf[i]; s->wng->writer_nodes[i].writer = a->writers[i]; - sprintf(s->wng->writer_nodes[i].task.status, "writer_ node"); + sprintf(s->wng->writer_nodes[i].task.status, "writer_node"); } - ret = wng_open(s->wng); + ret = wng_open(s->wng); /* FIXME */ s->wstime = *now; current_decoder = slot_num; activate_inactive_grab_clients(slot_num, s->format, &s->fc->filters); } -void rn_event_handler(struct task *t) +static void rn_event_handler(struct task *t) { // struct receiver_node *rn = t->private_data; PARA_NOTICE_LOG("%s\n", PARA_STRERROR(-t->ret)); unregister_task(t); } + static void open_receiver(int format) { struct audio_format_info *a = &afi[format]; @@ -751,8 +743,6 @@ static void open_receiver(int format) clean_exit(EXIT_FAILURE, PARA_STRERROR(-slot_num)); s = &slot[slot_num]; s->format = format; - gettimeofday(&s->rtime, NULL); - s->wtime = s->rtime; s->receiver_node = para_calloc(sizeof(struct receiver_node)); rn = s->receiver_node; rn->receiver = a->receiver; @@ -768,7 +758,6 @@ static void open_receiver(int format) PARA_NOTICE_LOG("started %s: %s receiver in slot %d\n", audio_formats[s->format], a->receiver->name, slot_num); rn->task.private_data = s->receiver_node; - PARA_NOTICE_LOG("rn = %p\n", rn->task.private_data); rn->task.pre_select = a->receiver->pre_select; rn->task.post_select = a->receiver->post_select; rn->task.event_handler = rn_event_handler; @@ -779,14 +768,12 @@ static void open_receiver(int format) static int is_frozen(int format) { - struct timeval now; struct audio_format_info *a = &afi[format]; - gettimeofday(&now, NULL); - return (tv_diff(&now, &a->restart_barrier, NULL) > 0)? 0 : 1; + return (tv_diff(now, &a->restart_barrier, NULL) > 0)? 0 : 1; } -static void start_current_receiver(void) +static void open_current_receiver(void) { int i; @@ -795,21 +782,20 @@ static void start_current_receiver(void) i = get_audio_format_num(af_status); if (i < 0) return; - if ((decoder_running(i) & 1) || is_frozen(i)) + if (decoder_running(i) || is_frozen(i)) return; open_receiver(i); } static void compute_time_diff(const struct timeval *status_time) { - struct timeval now, tmp, diff; + struct timeval tmp, diff; static int count; int sign; const struct timeval max_deviation = {0, 500 * 1000}; const int time_smooth = 5; - gettimeofday(&now, NULL); - sign = tv_diff(status_time, &now, &diff); + sign = tv_diff(status_time, now, &diff); // PARA_NOTICE_LOG("%s: sign = %i, sa_time_diff_sign = %i\n", __func__, // sign, sa_time_diff_sign); if (!count) { @@ -892,7 +878,12 @@ static void handle_signal(int sig) { switch (sig) { case SIGCHLD: - return check_sigchld(); + for (;;) { + pid_t pid = para_reap_child(); + if (pid <= 0) + return; + PARA_CRIT_LOG("para_client died (pid %d)\n", pid); + } case SIGINT: case SIGTERM: case SIGHUP: @@ -902,86 +893,75 @@ static void handle_signal(int sig) } } -static void check_timeouts(void) -{ - struct timeval now; - int slot_num, timeout = conf.stream_timeout_arg; - - gettimeofday(&now, NULL); - FOR_EACH_SLOT(slot_num) { - struct slot_info *s = &slot[slot_num]; - if (s->format < 0) - continue; - /* check read time */ - if (s->receiver_node && - now.tv_sec > s->rtime.tv_sec + timeout) { - PARA_INFO_LOG("%s stream (slot %d) not ready\n", - audio_formats[s->format], slot_num); - s->receiver_node->eof = 1; - } - } -} - -static void close_decoder_if_idle(int slot_num) +static void try_to_close_slot(int slot_num) { struct slot_info *s = &slot[slot_num]; if (s->format < 0) return; - if (!s->fc) + if (s->receiver_node && !s->receiver_node->eof) return; - if (s->wng) + if (s->fc && !s->fc->eof) return; - PARA_INFO_LOG("closing all filters in slot %d (filter_chain %p)\n", - slot_num, s->fc); + if (s->wng && !s->wng->eof) + return; + PARA_INFO_LOG("closing slot %d \n", slot_num); + wng_close(s->wng); close_filters(s->fc); free(s->fc); close_receiver(slot_num); clear_slot(slot_num); } -static void audiod_pre_select(__a_unused struct sched *s, __a_unused struct task *t) +static void audiod_pre_select(struct sched *s, __a_unused struct task *t) { int i; + t->ret = 1; + now = &s->now; if (audiod_status != AUDIOD_ON) kill_all_decoders(); else if (playing) - start_current_receiver(); - check_timeouts(); + open_current_receiver(); FOR_EACH_SLOT(i) { - struct receiver_node *rn; + struct slot_info *s = &slot[i]; + struct audio_format_info *a; - close_decoder_if_idle(i); - if (slot[i].format < 0) + try_to_close_slot(i); + if (s->format < 0) + continue; + a = &afi[s->format]; + if (!s->receiver_node) + continue; + if (!a->num_filters) { + if (s->receiver_node->loaded && !s->wng) + open_writers(i); + continue; + } + if (s->receiver_node->loaded && !s->fc) { + open_filters(i); continue; - rn = slot[i].receiver_node; - if (rn && rn->loaded && !slot[i].wng) { - PARA_INFO_LOG("no writer in slot %d\n", i); - start_stream_writer(i, &s->now); } + if (s->fc && *s->fc->out_loaded && !s->wng) + open_writers(i); } } static void audiod_post_select(struct sched *s, __a_unused struct task *t) { - int i; - - FOR_EACH_SLOT(i) { - struct receiver_node *rn = slot[i].receiver_node; - - if (rn && rn->loaded) - slot[i].rtime = s->now; - } + /* only save away the current time for other users */ + now = &s->now; + t->ret = 1; } -static void init_audiod_task(struct audiod_task *at) +static void init_audiod_task(struct task *t) { - at->task.pre_select = audiod_pre_select; - at->task.post_select = audiod_post_select; - at->task.private_data = at; - at->task.flags = 0; - sprintf(at->task.status, "audiod task"); + t->pre_select = audiod_pre_select; + t->post_select = audiod_post_select; + t->event_handler = NULL; + t->private_data = t; + t->flags = 0; + sprintf(t->status, "audiod task"); } static int parse_stream_command(const char *txt, char **cmd) @@ -1016,50 +996,15 @@ static int add_filter(int format, char *cmdline) return filter_num; } -static int setup_default_filters(void) -{ - int i, ret = 1; - - FOR_EACH_AUDIO_FORMAT(i) { - struct audio_format_info *a = &afi[i]; - char *tmp; - int j; - if (a->num_filters) - continue; - /* add "dec" to audio format name */ - tmp = make_message("%sdec", audio_formats[i]); - for (j = 0; filters[j].name; j++) - if (!strcmp(tmp, filters[j].name)) - break; - free(tmp); - ret = -E_UNSUPPORTED_FILTER; - if (!filters[j].name) - goto out; - tmp = para_strdup(filters[j].name); - ret = add_filter(i, tmp); - free(tmp); - if (ret < 0) - goto out; - PARA_INFO_LOG("%s -> default filter: %s\n", audio_formats[i], - filters[j].name); - ret = add_filter(i, "wav"); - if (ret < 0) - goto out; - PARA_INFO_LOG("%s -> default filter: wav\n", audio_formats[i]); - } -out: - return ret; -} - -static int init_stream_io(void) +static int init_writers(void) { - int i, ret, receiver_num, nf, nw; + int i, ret, nw; char *cmd; struct audio_format_info *a; init_supported_writers(); nw = PARA_MAX(1, conf.writer_given); - PARA_INFO_LOG("allocating space for %d writers\n", nw); + PARA_INFO_LOG("maximal number of writers: %d\n", nw); FOR_EACH_AUDIO_FORMAT(i) { a = &afi[i]; a->writer_conf = para_malloc(nw * sizeof(void *)); @@ -1079,12 +1024,23 @@ static int init_stream_io(void) ret = writer_num; goto out; } - a->writers[nw] = &writers[ret]; + a->writers[nw] = &writers[writer_num]; a->writer_conf[nw] = wconf; PARA_INFO_LOG("%s writer #%d: %s\n", audio_formats[ret], nw, writer_names[writer_num]); a->num_writers++; } + ret = 1; +out: + return ret; +} + +static int init_receivers(void) +{ + int i, ret, receiver_num; + char *cmd = NULL; + struct audio_format_info *a; + for (i = 0; receivers[i].name; i++) { PARA_INFO_LOG("initializing %s receiver\n", receivers[i].name); receivers[i].init(&receivers[i]); @@ -1121,17 +1077,57 @@ static int init_stream_io(void) return -E_RECV_SYNTAX; a->receiver = &receivers[receiver_num]; } + ret = 1; +out: free(cmd); - /* filters */ + return ret; +} + +static int init_default_filters(void) +{ + int i, ret = 1; + + FOR_EACH_AUDIO_FORMAT(i) { + struct audio_format_info *a = &afi[i]; + char *tmp; + int j; + + if (a->num_filters) + continue; /* no default -- nothing to to */ + /* add "dec" to audio format name */ + tmp = make_message("%sdec", audio_formats[i]); + for (j = 0; filters[j].name; j++) + if (!strcmp(tmp, filters[j].name)) + break; + free(tmp); + ret = -E_UNSUPPORTED_FILTER; + if (!filters[j].name) + goto out; + tmp = para_strdup(filters[j].name); + ret = add_filter(i, tmp); + free(tmp); + if (ret < 0) + goto out; + PARA_INFO_LOG("%s -> default filter: %s\n", audio_formats[i], + filters[j].name); + } +out: + return ret; +} + +static int init_filters(void) +{ + int i, ret, nf; + filter_init(filters); - nf = PARA_MAX(2, conf.filter_given) + 1; - PARA_INFO_LOG("allocating space for %d filters\n", nf); + nf = PARA_MAX(1, conf.filter_given); + PARA_INFO_LOG("maximal number of filters: %d\n", nf); FOR_EACH_AUDIO_FORMAT(i) { afi[i].filter_conf = para_malloc(nf * sizeof(void *)); afi[i].filters = para_malloc(nf * sizeof(struct filter *)); } if (!conf.no_default_filters_given) - return setup_default_filters(); + return init_default_filters(); for (i = 0; i < conf.filter_given; i++) { char *arg = conf.filter_arg[i]; char *filter_name = strchr(arg, ':'); @@ -1147,11 +1143,27 @@ static int init_stream_io(void) if (ret < 0) goto out; } - ret = 1; + ret = init_default_filters(); /* use default values for the rest */ out: return ret; } +static int init_stream_io(void) +{ + int ret; + + ret = init_writers(); + if (ret < 0) + return ret; + ret = init_receivers(); + if (ret < 0) + return ret; + ret = init_filters(); + if (ret < 0) + return ret; + return 1; +} + static int dump_commands(int fd) { char *buf = para_strdup(""), *tmp = NULL; @@ -1372,13 +1384,13 @@ static int check_perms(uid_t uid) return -E_UCRED_PERM; } -static int handle_connect(void) +static int handle_connect(int accept_fd) { int i, argc, ret, clifd = -1; char *cmd = NULL, *p, *buf = para_calloc(MAXLINE), **argv = NULL; struct sockaddr_un unix_addr; - ret = para_accept(cmd_task->fd, &unix_addr, sizeof(struct sockaddr_un)); + ret = para_accept(accept_fd, &unix_addr, sizeof(struct sockaddr_un)); if (ret < 0) goto out; clifd = ret; @@ -1429,9 +1441,10 @@ out: return ret; } -static void audiod_get_socket(void) +static int audiod_get_socket(void) { struct sockaddr_un unix_addr; + int fd; if (conf.socket_given) socket_name = para_strdup(conf.socket_arg); @@ -1441,20 +1454,21 @@ static void audiod_get_socket(void) hn); free(hn); } - PARA_NOTICE_LOG("connecting to local socket %s\n", socket_name); + PARA_NOTICE_LOG("local socket: %s\n", socket_name); if (conf.force_given) unlink(socket_name); - cmd_task->fd = create_pf_socket(socket_name, &unix_addr, + fd = create_pf_socket(socket_name, &unix_addr, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IWOTH); - if (cmd_task->fd < 0) { + if (fd < 0) { PARA_EMERG_LOG("%s", "can not connect to socket\n"); exit(EXIT_FAILURE); /* do not unlink socket */ } - if (listen(cmd_task->fd , 5) < 0) { + if (listen(fd , 5) < 0) { PARA_EMERG_LOG("%s", "can not listen on socket\n"); exit(EXIT_FAILURE); /* do not unlink socket */ } - add_close_on_fork_list(cmd_task->fd); + add_close_on_fork_list(fd); + return fd; } static int open_stat_pipe(void) @@ -1506,6 +1520,7 @@ void signal_setup_default(struct signal_task *st) static void command_pre_select(struct sched *s, struct task *t) { struct command_task *ct = t->private_data; + t->ret = 1; para_fd_set(ct->fd, &s->rfds, &s->max_fileno); } @@ -1515,22 +1530,24 @@ static void command_post_select(struct sched *s, struct task *t) int ret; struct command_task *ct = t->private_data; + t->ret = 1; /* always successful */ if (audiod_status != AUDIOD_OFF) audiod_status_dump(); - t->ret = 1; /* always successful */ if (!FD_ISSET(ct->fd, &s->rfds)) return; - ret = handle_connect(); + ret = handle_connect(ct->fd); if (ret < 0) PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret)); } -void init_command_task(struct command_task *ct) +static void init_command_task(struct command_task *ct) { ct->task.pre_select = command_pre_select; ct->task.post_select = command_post_select; + ct->task.event_handler = NULL; ct->task.private_data = ct; ct->task.flags = 0; + ct->fd = audiod_get_socket(); /* doesn't return on errors */ sprintf(ct->task.status, "command task"); } @@ -1562,7 +1579,7 @@ static void status_post_select(struct sched *s, struct task *t) if (ret <= 0) { close_stat_pipe(); /* avoid busy loop if server is down */ - while (sleep(1) > 0) + while (sleep(1) > 0) /* FIXME */ ; /* try again*/ } else { st->buf[ret + st->loaded] = '\0'; @@ -1605,6 +1622,8 @@ int main(int argc, char *argv[]) char *cf; int ret, i; struct sched s; + struct command_task command_task_struct, *cmd_task = &command_task_struct; + struct task audiod_task_struct, *audiod_task = &audiod_task_struct; init_sched(); @@ -1633,21 +1652,20 @@ int main(int argc, char *argv[]) clear_slot(i); init_grabbing(); setup_signal_handling(); - if (conf.daemon_given) - daemon_init(); - audiod_get_socket(); /* doesn't return on errors */ - signal_setup_default(sig_task); sig_task->task.event_handler = signal_event_handler; init_status_task(stat_task); init_command_task(cmd_task); - init_audiod_task(at); + init_audiod_task(audiod_task); + + if (conf.daemon_given) + daemon_init(); register_task(&sig_task->task); register_task(&cmd_task->task); register_task(&stat_task->task); - register_task(&at->task); + register_task(audiod_task); s.default_timeout.tv_sec = 0; s.default_timeout.tv_usec = 99 * 1000; ret = sched(&s);