From 945190584beab2f767f0109af9e3fb89e2b814f9 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Thu, 6 Oct 2022 16:11:55 +0200 Subject: [PATCH] play: Shut down alsa on input EOF. --- play.c | 61 ++++++++++++++++++---------------------------------------- 1 file changed, 19 insertions(+), 42 deletions(-) diff --git a/play.c b/play.c index f04cf842..c9a9f7d7 100644 --- a/play.c +++ b/play.c @@ -1091,39 +1091,6 @@ static void session_update_time_string(char *str, unsigned len) i9e_print_status_bar(str, len); } -/* - * If we are about to die we must call i9e_close() to reset the terminal. - * However, i9e_close() must be called in *this* context, i.e. from - * play_task.post_monitor() rather than from i9e_post_monitor(), because - * otherwise i9e would access freed memory upon return. So the play task must - * stay alive until the i9e task terminates. - * - * We achieve this by sending a fake SIGTERM signal via i9e_signal_dispatch() - * and reschedule. In the next iteration, i9e->post_monitor returns an error and - * terminates. Subsequent calls to i9e_get_error() then return negative and we - * are allowed to call i9e_close() and terminate as well. - */ -static int session_post_monitor(__a_unused struct sched *s) -{ - int ret; - - if (pt->background) - detach_stdout(); - else - attach_stdout(__FUNCTION__); - ret = i9e_get_error(); - if (ret < 0) { - kill_stream(); - i9e_close(); - para_log = stderr_log; - free(ici.history_file); - return ret; - } - if (get_playback_state() == 'X') - i9e_signal_dispatch(SIGTERM); - return 0; -} - static void play_pre_monitor(struct sched *s, __a_unused void *context) { char state; @@ -1162,18 +1129,24 @@ static unsigned get_time_string(char **result) ); } -static int play_post_monitor(struct sched *s, __a_unused void *context) +static int play_post_monitor(__a_unused struct sched *s, __a_unused void *context) { - int ret; + int ret, i9e_error; + if (pt->background) + detach_stdout(); + else + attach_stdout(__FUNCTION__); + i9e_error = i9e_get_error(); ret = eof_cleanup(); - if (ret < 0) { - pt->rq = CRT_TERM_RQ; - return 0; - } - ret = session_post_monitor(s); - if (ret < 0) - goto out; + if (pt->rq == CRT_TERM_RQ || i9e_error < 0) /* com_quit() or CTRL+D */ + kill_stream(); /* terminate receiver/filter/writer */ + if ((ret < 0 || pt->rq == CRT_TERM_RQ) && i9e_error >= 0) + i9e_signal_dispatch(SIGTERM); /* terminate the i9e task */ + if (ret < 0) /* unexpected error from the writer node */ + return ret; + if (ret != 0 && i9e_error < 0) /* eof, and i9e has died */ + return i9e_error; if (!pt->wn.btrn && !pt->fn.btrn) { char state = get_playback_state(); if (state == 'P' || state == 'R' || state == 'F') { @@ -1243,6 +1216,10 @@ int main(int argc, char *argv[]) }, &sched); ret = schedule(&sched); sched_shutdown(&sched); + i9e_close(); + wipe_receiver_node(); + para_log = stderr_log; + free(ici.history_file); if (ret < 0) PARA_ERROR_LOG("%s\n", para_strerror(-ret)); return ret < 0? EXIT_FAILURE : EXIT_SUCCESS; -- 2.39.2