To: vim_dev@googlegroups.com Subject: Patch 8.1.0304 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.0304 Problem: No redraw when using a STOP signal on Vim and then a CONT signal. Solution: Catch the CONT signal and set the terminal to raw mode. This is like 8.1.0244 but without the screen redraw and a fix for multi-threading suggested by Dominique Pelle. Files: src/os_unix.c, src/term.c, src/proto/term.pro *** ../vim-8.1.0303/src/os_unix.c 2018-08-20 21:58:53.505410802 +0200 --- src/os_unix.c 2018-08-21 13:01:23.341522963 +0200 *************** *** 1228,1241 **** SIGRETURN; } - #if defined(_REENTRANT) && defined(SIGCONT) /* ! * On Solaris with multi-threading, suspending might not work immediately. ! * Catch the SIGCONT signal, which will be used as an indication whether the ! * suspending has been done or not. * * On Linux, signal is not always handled immediately either. * See https://bugs.launchpad.net/bugs/291373 * * volatile because it is used in signal handler sigcont_handler(). */ --- 1228,1262 ---- SIGRETURN; } /* ! * Invoked after receiving SIGCONT. We don't know what happened while ! * sleeping, deal with part of that. ! */ ! static void ! after_sigcont(void) ! { ! # ifdef FEAT_TITLE ! // Don't change "oldtitle" in a signal handler, set a flag to obtain it ! // again later. ! oldtitle_outdated = TRUE; ! # endif ! settmode(TMODE_RAW); ! need_check_timestamps = TRUE; ! did_check_timestamps = FALSE; ! } ! ! #if defined(SIGCONT) ! static RETSIGTYPE sigcont_handler SIGPROTOARG; ! static volatile int in_mch_suspend = FALSE; ! ! /* ! * With multi-threading, suspending might not work immediately. Catch the ! * SIGCONT signal, which will be used as an indication whether the suspending ! * has been done or not. * * On Linux, signal is not always handled immediately either. * See https://bugs.launchpad.net/bugs/291373 + * Probably because the signal is handled in another thread. * * volatile because it is used in signal handler sigcont_handler(). */ *************** *** 1248,1254 **** static RETSIGTYPE sigcont_handler SIGDEFARG(sigarg) { ! sigcont_received = TRUE; SIGRETURN; } #endif --- 1269,1290 ---- static RETSIGTYPE sigcont_handler SIGDEFARG(sigarg) { ! if (in_mch_suspend) ! { ! sigcont_received = TRUE; ! } ! else ! { ! // We didn't suspend ourselves, assume we were stopped by a SIGSTOP ! // signal (which can't be intercepted) and get a SIGCONT. Need to get ! // back to a sane mode. We should redraw, but we can't really do that ! // in a signal handler, do a redraw later. ! after_sigcont(); ! redraw_later(CLEAR); ! cursor_on_force(); ! out_flush(); ! } ! SIGRETURN; } #endif *************** *** 1331,1336 **** --- 1367,1374 ---- { /* BeOS does have SIGTSTP, but it doesn't work. */ #if defined(SIGTSTP) && !defined(__BEOS__) + in_mch_suspend = TRUE; + out_flush(); /* needed to make cursor visible on some systems */ settmode(TMODE_COOK); out_flush(); /* needed to disable mouse on some systems */ *************** *** 1338,1377 **** # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11) loose_clipboard(); # endif ! ! # if defined(_REENTRANT) && defined(SIGCONT) sigcont_received = FALSE; # endif kill(0, SIGTSTP); /* send ourselves a STOP signal */ ! # if defined(_REENTRANT) && defined(SIGCONT) /* * Wait for the SIGCONT signal to be handled. It generally happens ! * immediately, but somehow not all the time. Do not call pause() ! * because there would be race condition which would hang Vim if ! * signal happened in between the test of sigcont_received and the ! * call to pause(). If signal is not yet received, call sleep(0) ! * to just yield CPU. Signal should then be received. If somehow ! * it's still not received, sleep 1, 2, 3 ms. Don't bother waiting ! * further if signal is not received after 1+2+3+4 ms (not expected ! * to happen). */ { long wait_time; for (wait_time = 0; !sigcont_received && wait_time <= 3L; wait_time++) - /* Loop is not entered most of the time */ mch_delay(wait_time, FALSE); } # endif ! # ifdef FEAT_TITLE ! /* ! * Set oldtitle to NULL, so the current title is obtained again. ! */ ! VIM_CLEAR(oldtitle); ! # endif ! settmode(TMODE_RAW); ! need_check_timestamps = TRUE; ! did_check_timestamps = FALSE; #else suspend_shell(); #endif --- 1376,1407 ---- # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11) loose_clipboard(); # endif ! # if defined(SIGCONT) sigcont_received = FALSE; # endif + kill(0, SIGTSTP); /* send ourselves a STOP signal */ ! ! # if defined(SIGCONT) /* * Wait for the SIGCONT signal to be handled. It generally happens ! * immediately, but somehow not all the time, probably because it's handled ! * in another thread. Do not call pause() because there would be race ! * condition which would hang Vim if signal happened in between the test of ! * sigcont_received and the call to pause(). If signal is not yet received, ! * sleep 0, 1, 2, 3 ms. Don't bother waiting further if signal is not ! * received after 1+2+3 ms (not expected to happen). */ { long wait_time; + for (wait_time = 0; !sigcont_received && wait_time <= 3L; wait_time++) mch_delay(wait_time, FALSE); } # endif + in_mch_suspend = FALSE; ! after_sigcont(); #else suspend_shell(); #endif *************** *** 1411,1417 **** #ifdef SIGTSTP signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL); #endif ! #if defined(_REENTRANT) && defined(SIGCONT) signal(SIGCONT, sigcont_handler); #endif --- 1441,1447 ---- #ifdef SIGTSTP signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL); #endif ! #if defined(SIGCONT) signal(SIGCONT, sigcont_handler); #endif *************** *** 1470,1476 **** reset_signals(void) { catch_signals(SIG_DFL, SIG_DFL); ! #if defined(_REENTRANT) && defined(SIGCONT) /* SIGCONT isn't in the list, because its default action is ignore */ signal(SIGCONT, SIG_DFL); #endif --- 1500,1506 ---- reset_signals(void) { catch_signals(SIG_DFL, SIG_DFL); ! #if defined(SIGCONT) /* SIGCONT isn't in the list, because its default action is ignore */ signal(SIGCONT, SIG_DFL); #endif *************** *** 1533,1539 **** for (i = 0; signal_info[i].sig != -1; i++) sigaddset(&newset, signal_info[i].sig); ! # if defined(_REENTRANT) && defined(SIGCONT) /* SIGCONT isn't in the list, because its default action is ignore */ sigaddset(&newset, SIGCONT); # endif --- 1563,1569 ---- for (i = 0; signal_info[i].sig != -1; i++) sigaddset(&newset, signal_info[i].sig); ! # if defined(SIGCONT) /* SIGCONT isn't in the list, because its default action is ignore */ sigaddset(&newset, SIGCONT); # endif *** ../vim-8.1.0303/src/term.c 2018-08-20 21:58:53.505410802 +0200 --- src/term.c 2018-08-21 12:55:46.236289405 +0200 *************** *** 3834,3849 **** static int cursor_is_off = FALSE; /* ! * Enable the cursor. */ void cursor_on(void) { if (cursor_is_off) ! { ! out_str(T_VE); ! cursor_is_off = FALSE; ! } } /* --- 3834,3856 ---- static int cursor_is_off = FALSE; /* ! * Enable the cursor without checking if it's already enabled. ! */ ! void ! cursor_on_force(void) ! { ! out_str(T_VE); ! cursor_is_off = FALSE; ! } ! ! /* ! * Enable the cursor if it's currently off. */ void cursor_on(void) { if (cursor_is_off) ! cursor_on_force(); } /* *** ../vim-8.1.0303/src/proto/term.pro 2018-08-20 21:58:53.509410779 +0200 --- src/proto/term.pro 2018-08-21 12:55:54.468217234 +0200 *************** *** 52,57 **** --- 52,58 ---- int mouse_has(int c); int mouse_model_popup(void); void scroll_start(void); + void cursor_on_force(void); void cursor_on(void); void cursor_off(void); void term_cursor_mode(int forced); *** ../vim-8.1.0303/src/version.c 2018-08-20 22:53:00.210105086 +0200 --- src/version.c 2018-08-21 12:40:20.807634438 +0200 *************** *** 796,797 **** --- 796,799 ---- { /* Add new patch number below this line */ + /**/ + 304, /**/ -- I used to wonder about the meaning of life. But I looked it up in the dictionary under "L" and there it was - the meaning of life. It was less than I expected. - Dogbert /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///