]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
play: Shut down alsa on input EOF.
authorAndre Noll <maan@tuebingen.mpg.de>
Thu, 6 Oct 2022 14:11:55 +0000 (16:11 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Sun, 17 Mar 2024 11:35:07 +0000 (12:35 +0100)
play.c

diff --git a/play.c b/play.c
index f04cf842d94f2c42e44c79542498ccd16703c2cb..c9a9f7d7e8a69a0d2db51d3fdbdc8e04aec1c6d7 100644 (file)
--- 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;