X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=audiod.c;h=9f2aa5ab6960f08c9affdd919ae04b26f73b039c;hp=112f632de8c1f23cfdd893ae03fdb5c9e6a89d00;hb=d1fc17a64ea26ddcf34d044e6d51c884b368c66c;hpb=b1bf3612a6a5f0381fe6c12b96c73d1bbcbe7d56 diff --git a/audiod.c b/audiod.c index 112f632d..9f2aa5ab 100644 --- a/audiod.c +++ b/audiod.c @@ -77,6 +77,12 @@ enum vss_status_flags { VSS_STATUS_FLAG_PLAYING = 2, }; +/** + * The scheduler instance of para_audiod. + * + * This is needed also in audiod_command.c (for the tasks command), so it can + * not be made static. + */ struct sched sched = {.max_fileno = 0}; /** @@ -244,7 +250,7 @@ char *get_time_string(int slot_num) */ length = stat_task->length_seconds; tmp = &stat_task->server_stream_start; - if (s && s->wns) { /* writer active in this slot */ + if (s && s->wns && s->wns[0].btrn) { /* writer active in this slot */ 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) { @@ -261,7 +267,7 @@ char *get_time_string(int slot_num) tv_diff(tmp, &stat_task->sa_time_diff, &sss); else tv_add(tmp, &stat_task->sa_time_diff, &sss); - if (!s || !s->wns) { + if (!s || !s->wns || !s->wns[0].btrn) { struct timeval diff; tv_diff(now, &sss, &diff); seconds = diff.tv_sec + stat_task->offset_seconds; @@ -270,11 +276,14 @@ char *get_time_string(int slot_num) tv_diff(now, &wstime, &wtime); //PARA_CRIT_LOG("offset %d\n", s->offset_seconds); seconds = s->offset_seconds; - btr_get_node_start(s->receiver_node->btrn, &rstime); - ret = tv_diff(&rstime, &sss, &rskip); - if (ret > 0) { /* audiod was started in the middle of the stream */ - tv_add(&wtime, &rskip, &sum); - seconds += sum.tv_sec; + if (s->receiver_node->btrn) { + btr_get_node_start(s->receiver_node->btrn, &rstime); + ret = tv_diff(&rstime, &sss, &rskip); + if (ret > 0) { /* audiod was started in the middle of the stream */ + tv_add(&wtime, &rskip, &sum); + seconds += sum.tv_sec; + } else + seconds += wtime.tv_sec; } else seconds += wtime.tv_sec; out: @@ -372,7 +381,7 @@ static void close_receiver(int slot_num) PARA_NOTICE_LOG("closing %s receiver in slot %d\n", audio_formats[s->format], slot_num); a->receiver->close(s->receiver_node); - btr_free_node(s->receiver_node->btrn); + btr_remove_node(&s->receiver_node->btrn); free(s->receiver_node); s->receiver_node = NULL; tv_add(now, &(struct timeval)EMBRACE(0, 200 * 1000), @@ -388,7 +397,7 @@ static void writer_cleanup(struct writer_node *wn) w = writers + wn->writer_num; PARA_INFO_LOG("closing %s\n", writer_names[wn->writer_num]); w->close(wn); - btr_free_node(wn->btrn); + btr_remove_node(&wn->btrn); } static void close_writers(struct slot_info *s) @@ -425,7 +434,7 @@ static void close_filters(struct slot_info *s) f = filters + fn->filter_num; if (f->close) f->close(fn); - btr_free_node(fn->btrn); + btr_remove_node(&fn->btrn); } free(s->fns); s->fns = NULL; @@ -437,12 +446,12 @@ static void close_filters(struct slot_info *s) * task. Note that the scheduler checks t->error also _before_ each pre/post * select call, so the victim will never be scheduled again. */ -static void kill_btrn(struct btr_node *btrn, struct task *t, int error) +static void kill_btrn(struct btr_node **btrnp, struct task *t, int error) { if (t->error < 0) return; t->error = error; - btr_remove_node(btrn); + btr_remove_node(btrnp); } static void kill_all_decoders(int error) @@ -455,7 +464,7 @@ static void kill_all_decoders(int error) continue; if (!s->receiver_node) continue; - kill_btrn(s->receiver_node->btrn, &s->receiver_node->task, + kill_btrn(&s->receiver_node->btrn, &s->receiver_node->task, error); } } @@ -554,7 +563,7 @@ static int open_receiver(int format) EMBRACE(.name = r->name, .context = rn)); ret = r->open(rn); if (ret < 0) { - btr_free_node(rn->btrn); + btr_remove_node(&rn->btrn); free(rn); return ret; } @@ -1187,11 +1196,9 @@ static void status_post_select(struct sched *s, struct task *t) if (!st->ct) goto out; if (st->ct->task.error >= 0) { - kill_btrn(st->ct->btrn, &st->ct->task, -E_AUDIOD_OFF); + kill_btrn(&st->ct->btrn, &st->ct->task, -E_AUDIOD_OFF); goto out; } - if (st->ct->task.error >= 0) - goto out; close_stat_pipe(); st->clock_diff_count = conf.clock_diff_count_arg; goto out; @@ -1201,8 +1208,6 @@ static void status_post_select(struct sched *s, struct task *t) size_t sz; int ret; if (st->ct->task.error < 0) { - if (st->ct->task.error >= 0) - goto out; close_stat_pipe(); goto out; } @@ -1213,7 +1218,7 @@ static void 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) - kill_btrn(st->ct->btrn, &st->ct->task, + kill_btrn(&st->ct->btrn, &st->ct->task, -E_STATUS_TIMEOUT); goto out; } @@ -1221,7 +1226,7 @@ static void status_post_select(struct sched *s, struct task *t) sz = btr_next_buffer(st->btrn, &buf); ret = for_each_stat_item(buf, sz, update_item); if (ret < 0) { - kill_btrn(st->ct->btrn, &st->ct->task, ret); + kill_btrn(&st->ct->btrn, &st->ct->task, ret); goto out; } if (sz != ret) {