To: vim_dev@googlegroups.com Subject: Patch 8.2.3640 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3640 Problem: Freeze when calling term_wait() in a close callback. Solution: Set a "closing" flag to tell term_wait() to return. (closes #9152) Files: src/channel.c, src/terminal.c, src/proto/terminal.pro, src/testdir/test_terminal.vim *** ../vim-8.2.3639/src/channel.c 2021-09-08 13:57:38.233188064 +0100 --- src/channel.c 2021-11-21 14:33:20.956234348 +0000 *************** *** 3156,3161 **** --- 3156,3165 ---- { ch_part_T part; + #ifdef FEAT_TERMINAL + // let the terminal know it is closing to avoid getting stuck + term_channel_closing(channel); + #endif // Invoke callbacks and flush buffers before the close callback. if (channel->ch_close_cb.cb_name != NULL) ch_log(channel, *** ../vim-8.2.3639/src/terminal.c 2021-11-20 13:45:37.810729599 +0000 --- src/terminal.c 2021-11-21 14:48:21.217602864 +0000 *************** *** 99,104 **** --- 99,105 ---- int tl_vterm_size_changed; int tl_normal_mode; // TRUE: Terminal-Normal mode + int tl_channel_closing; int tl_channel_closed; int tl_channel_recently_closed; // still need to handle tl_finish *************** *** 3459,3464 **** --- 3460,3479 ---- #endif /* + * Called when a channel is going to be closed, before invoking the close + * callback. + */ + void + term_channel_closing(channel_T *ch) + { + term_T *term; + + for (term = first_term; term != NULL; term = term->tl_next) + if (term->tl_job == ch->ch_job && !term->tl_channel_closed) + term->tl_channel_closing = TRUE; + } + + /* * Called when a channel has been closed. * If this was a channel for a terminal window then finish it up. */ *************** *** 6438,6443 **** --- 6453,6461 ---- // If the terminal is closed when the channel is closed the // buffer disappears. break; + if (buf->b_term == NULL || buf->b_term->tl_channel_closing) + // came here from a close callback, only wait one time + break; } term_flush_messages(); *** ../vim-8.2.3639/src/proto/terminal.pro 2021-11-20 13:45:37.806729612 +0000 --- src/proto/terminal.pro 2021-11-21 14:38:42.599163461 +0000 *************** *** 20,25 **** --- 20,26 ---- void term_win_entered(void); int terminal_loop(int blocking); int may_close_term_popup(void); + void term_channel_closing(channel_T *ch); void term_channel_closed(channel_T *ch); void term_check_channel_closed_recently(void); int term_do_update_window(win_T *wp); *** ../vim-8.2.3639/src/testdir/test_terminal.vim 2021-11-19 17:01:05.559037762 +0000 --- src/testdir/test_terminal.vim 2021-11-21 14:47:06.217790097 +0000 *************** *** 2058,2062 **** --- 2058,2079 ---- bwipe! endfunc + func Close_cb(ch, ctx) + call term_wait(a:ctx.bufnr) + let g:close_done = 'done' + endfunc + + func Test_term_wait_in_close_cb() + let g:close_done = '' + let ctx = {} + let ctx.bufnr = term_start('echo "HELLO WORLD"', + \ {'close_cb': {ch -> Close_cb(ch, ctx)}}) + + call WaitForAssert({-> assert_equal("done", g:close_done)}) + + unlet g:close_done + bwipe! + endfunc + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.3639/src/version.c 2021-11-21 12:27:09.954898888 +0000 --- src/version.c 2021-11-21 14:34:29.819985168 +0000 *************** *** 759,760 **** --- 759,762 ---- { /* Add new patch number below this line */ + /**/ + 3640, /**/ -- I wonder, do vegetarians eat fruit bats? /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///