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 -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui