X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=audiod.c;h=ee1364433e77de965e715fe59692040e6e590989;hp=a8f401834b8a438d7b21d96920bc7b735f0a6c6b;hb=c52b8398d68a87d8fac858f6681dee5f0b09289d;hpb=f76ab46a9216133332cb7e17d38d392caeca22cb diff --git a/audiod.c b/audiod.c index a8f40183..ee136443 100644 --- a/audiod.c +++ b/audiod.c @@ -100,7 +100,7 @@ struct sched sched = {.max_fileno = 0}; */ struct status_task { /** The associated task structure of audiod. */ - struct task task; + struct task *task; /** Client data associated with the stat task. */ struct client_task *ct; /** Do not restart client command until this time. */ @@ -168,7 +168,7 @@ struct command_task { /** the local listening socket */ int fd; /** the associated task structure */ - struct task task; + struct task *task; }; /** iterate over all supported audio formats */ @@ -391,6 +391,7 @@ static void close_receiver(int slot_num) audio_formats[s->format], slot_num); a->receiver->close(s->receiver_node); btr_remove_node(&s->receiver_node->btrn); + task_reap(&s->receiver_node->task); free(s->receiver_node); s->receiver_node = NULL; tv_add(now, &(struct timeval)EMBRACE(0, 200 * 1000), @@ -407,6 +408,7 @@ static void writer_cleanup(struct writer_node *wn) PARA_INFO_LOG("closing %s\n", writer_names[wn->writer_num]); w->close(wn); btr_remove_node(&wn->btrn); + task_reap(&wn->task); } static void close_writers(struct slot_info *s) @@ -444,6 +446,7 @@ static void close_filters(struct slot_info *s) if (f->close) f->close(fn); btr_remove_node(&fn->btrn); + task_reap(&fn->task); } free(s->fns); s->fns = NULL; @@ -459,7 +462,7 @@ static void notify_receivers(int error) continue; if (!s->receiver_node) continue; - task_notify(&s->receiver_node->task, error); + task_notify(s->receiver_node->task, error); } } @@ -497,22 +500,26 @@ static void open_filters(struct slot_info *s) s->fns = para_calloc(nf * sizeof(struct filter_node)); parent = s->receiver_node->btrn; for (i = 0; i < nf; i++) { + char buf[20]; struct filter *f = filters + a->filter_nums[i]; fn = s->fns + i; fn->filter_num = a->filter_nums[i]; fn->conf = a->filter_conf[i]; - fn->task.pre_select = f->pre_select; - fn->task.post_select = f->post_select; fn->btrn = btr_new_node(&(struct btr_node_description) EMBRACE(.name = f->name, .parent = parent, .handler = f->execute, .context = fn)); f->open(fn); - register_task(&sched, &fn->task); + sprintf(buf, "%s (slot %d)", f->name, (int)(s - slot)); + fn->task = task_register(&(struct task_info) { + .name = buf, + .pre_select = f->pre_select, + .post_select = f->post_select, + .context = fn, + }, &sched); parent = fn->btrn; PARA_NOTICE_LOG("%s filter %d/%d (%s) started in slot %d\n", audio_formats[s->format], i, nf, f->name, (int)(s - slot)); - sprintf(fn->task.status, "%s (slot %d)", f->name, (int)(s - slot)); } } @@ -566,10 +573,12 @@ static int open_receiver(int format) s->receiver_node = rn; PARA_NOTICE_LOG("started %s: %s receiver in slot %d\n", audio_formats[format], r->name, slot_num); - rn->task.pre_select = r->pre_select; - rn->task.post_select = r->post_select; - sprintf(rn->task.status, "%s receiver node", r->name); - register_task(&sched, &rn->task); + rn->task = task_register(&(struct task_info) { + .name = r->name, + .pre_select = r->pre_select, + .post_select = r->post_select, + .context = rn, + }, &sched); return slot_num; } @@ -584,7 +593,7 @@ static bool receiver_running(void) if (!s->receiver_node) continue; - if (s->receiver_node->task.error >= 0) + if (task_status(s->receiver_node->task) >= 0) return true; if (ss1 == ss2) return true; @@ -611,7 +620,7 @@ struct btr_node *audiod_get_btr_root(void) struct timeval rstime; if (!s->receiver_node) continue; - if (s->receiver_node->task.error < 0) + if (task_status(s->receiver_node->task) < 0) continue; btr_get_node_start(s->receiver_node->btrn, &rstime); if (newest_slot >= 0 && tv_diff(&rstime, &newest_rstime, NULL) < 0) @@ -997,7 +1006,7 @@ err: static void signal_pre_select(struct sched *s, struct task *t) { - struct signal_task *st = container_of(t, struct signal_task, task); + struct signal_task *st = task_context(t); para_fd_set(st->fd, &s->rfds, &s->max_fileno); } @@ -1016,23 +1025,16 @@ static int signal_post_select(struct sched *s, __a_unused struct task *t) return 0; } -static void signal_setup_default(struct signal_task *st) -{ - st->task.pre_select = signal_pre_select; - st->task.post_select = signal_post_select; - sprintf(st->task.status, "signal task"); -} - static void command_pre_select(struct sched *s, struct task *t) { - struct command_task *ct = container_of(t, struct command_task, task); + struct command_task *ct = task_context(t); para_fd_set(ct->fd, &s->rfds, &s->max_fileno); } static int command_post_select(struct sched *s, struct task *t) { int ret; - struct command_task *ct = container_of(t, struct command_task, task); + struct command_task *ct = task_context(t); static struct timeval last_status_dump; struct timeval tmp, delay; bool force = true; @@ -1067,11 +1069,14 @@ dump: 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.error = 0; ct->fd = audiod_get_socket(); /* doesn't return on errors */ - sprintf(ct->task.status, "command task"); + + ct->task = task_register(&(struct task_info) { + .name = "command", + .pre_select = command_pre_select, + .post_select = command_post_select, + .context = ct, + }, &sched); } static void close_stat_pipe(void) @@ -1079,6 +1084,7 @@ static void close_stat_pipe(void) if (!stat_task->ct) return; client_close(stat_task->ct); + task_reap(&stat_task->ct->task); stat_task->ct = NULL; clear_and_dump_items(); stat_task->length_seconds = 0; @@ -1103,17 +1109,17 @@ static bool must_close_slot(int slot_num) if (s->format < 0) return false; - if (s->receiver_node && s->receiver_node->task.error >= 0) + if (s->receiver_node && task_status(s->receiver_node->task) >= 0) return false; for (i = 0; i < a->num_filters; i++) - if (s->fns && s->fns[i].task.error >= 0) + if (s->fns && task_status(s->fns[i].task) >= 0) return false; if (a->num_writers > 0) { for (i = 0; i < a->num_writers; i++) - if (s->wns && s->wns[i].task.error >= 0) + if (s->wns && task_status(s->wns[i].task) >= 0) return false; } else { - if (s->wns && s->wns[0].task.error >= 0) + if (s->wns && task_status(s->wns[0].task) >= 0) return false; } return true; @@ -1171,7 +1177,6 @@ static void start_stop_decoders(void) { int ret; struct slot_info *sl; - struct audio_format_info *a; close_unused_slots(); if (audiod_status != AUDIOD_ON || @@ -1185,9 +1190,7 @@ static void start_stop_decoders(void) return; } sl = slot + ret; - a = afi + sl->format; - if (a->num_filters) - open_filters(sl); + open_filters(sl); open_writers(sl); activate_grab_clients(&sched); btr_log_tree(sl->receiver_node->btrn, LL_NOTICE); @@ -1195,7 +1198,7 @@ static void start_stop_decoders(void) static void status_pre_select(struct sched *s, struct task *t) { - struct status_task *st = container_of(t, struct status_task, task); + struct status_task *st = task_context(t); int i, ret, cafn = stat_task->current_audio_format_num; if (must_start_decoder()) @@ -1227,13 +1230,13 @@ min_delay: /* restart the client task if necessary */ static int status_post_select(struct sched *s, struct task *t) { - struct status_task *st = container_of(t, struct status_task, task); + struct status_task *st = task_context(t); if (audiod_status == AUDIOD_OFF) { if (!st->ct) goto out; - if (st->ct->task.error >= 0) { - task_notify(&st->ct->task, E_AUDIOD_OFF); + if (task_status(st->ct->task) >= 0) { + task_notify(st->ct->task, E_AUDIOD_OFF); goto out; } close_stat_pipe(); @@ -1256,14 +1259,14 @@ static int status_post_select(struct sched *s, struct task *t) struct timeval diff; tv_diff(now, &st->last_status_read, &diff); if (diff.tv_sec > 61) - task_notify(&st->ct->task, E_STATUS_TIMEOUT); + task_notify(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) { - task_notify(&st->ct->task, -ret); + task_notify(st->ct->task, -ret); goto out; } if (sz != ret) { @@ -1305,14 +1308,18 @@ out: static void init_status_task(struct status_task *st) { memset(st, 0, sizeof(struct status_task)); - st->task.pre_select = status_pre_select; - st->task.post_select = status_post_select; st->sa_time_diff_sign = 1; st->clock_diff_count = conf.clock_diff_count_arg; st->current_audio_format_num = -1; - sprintf(st->task.status, "stat"); st->btrn = btr_new_node(&(struct btr_node_description) EMBRACE(.name = "stat")); + + stat_task->task = task_register(&(struct task_info) { + .name = "stat", + .pre_select = status_pre_select, + .post_select = status_post_select, + .context = stat_task, + }, &sched); } static void set_initial_status(void) @@ -1416,7 +1423,6 @@ int main(int argc, char *argv[]) FOR_EACH_SLOT(i) clear_slot(i); setup_signal_handling(); - signal_setup_default(sig_task); init_status_task(stat_task); init_command_task(cmd_task); @@ -1424,12 +1430,17 @@ int main(int argc, char *argv[]) if (conf.daemon_given) daemonize(false /* parent exits immediately */); - register_task(&sched, &sig_task->task); - register_task(&sched, &cmd_task->task); - register_task(&sched, &stat_task->task); + sig_task->task = task_register(&(struct task_info) { + .name = "signal", + .pre_select = signal_pre_select, + .post_select = signal_post_select, + .context = sig_task, + }, &sched); + sched.default_timeout.tv_sec = 2; sched.default_timeout.tv_usec = 999 * 1000; ret = schedule(&sched); + sched_shutdown(&sched); PARA_EMERG_LOG("%s\n", para_strerror(-ret)); return EXIT_FAILURE;