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;
);
}
-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)
+ 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') {
}, &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;