Patch 8.0.0097
Problem:    When a channel callback consumes a lot of time Vim becomes
            unresponsive. (skywind)
Solution:   Bail out of checking channel readahead after 100 msec.
Files:      src/os_unix.c, src/misc2.c, src/vim.h, src/os_win32.c


*** ../vim-8.0.0096/src/os_unix.c       2016-11-17 17:25:28.212093109 +0100
--- src/os_unix.c       2016-11-24 17:10:57.847711807 +0100
***************
*** 376,396 ****
        RealWaitForChar(read_cmd_fd, p_wd, NULL, NULL);
  }
  
- #if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
- /*
-  * Return time in msec since "start_tv".
-  */
-     static long
- elapsed(struct timeval *start_tv)
- {
-     struct timeval  now_tv;
- 
-     gettimeofday(&now_tv, NULL);
-     return (now_tv.tv_sec - start_tv->tv_sec) * 1000L
-        + (now_tv.tv_usec - start_tv->tv_usec) / 1000L;
- }
- #endif
- 
  /*
   * mch_inchar(): low level input function.
   * Get a characters from the keyboard.
--- 376,381 ----
***************
*** 411,420 ****
      int               did_start_blocking = FALSE;
      long      wait_time;
      long      elapsed_time = 0;
! #if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
!     struct timeval  start_tv;
  
!     gettimeofday(&start_tv, NULL);
  #endif
  
      /* repeat until we got a character or waited long enough */
--- 396,405 ----
      int               did_start_blocking = FALSE;
      long      wait_time;
      long      elapsed_time = 0;
! #ifdef ELAPSED_FUNC
!     ELAPSED_TYPE start_tv;
  
!     ELAPSED_INIT(start_tv);
  #endif
  
      /* repeat until we got a character or waited long enough */
***************
*** 438,445 ****
            else
                /* going to block after p_ut */
                wait_time = p_ut;
! #if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
!           elapsed_time = elapsed(&start_tv);
  #endif
            wait_time -= elapsed_time;
            if (wait_time < 0)
--- 423,430 ----
            else
                /* going to block after p_ut */
                wait_time = p_ut;
! #ifdef ELAPSED_FUNC
!           elapsed_time = ELAPSED_FUNC(start_tv);
  #endif
            wait_time -= elapsed_time;
            if (wait_time < 0)
***************
*** 1554,1571 ****
  
  #ifdef FEAT_X11
  
! # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) \
        && (defined(FEAT_XCLIPBOARD) || defined(FEAT_TITLE))
  
- static void xopen_message(struct timeval *start_tv);
- 
  /*
   * Give a message about the elapsed time for opening the X window.
   */
      static void
! xopen_message(struct timeval *start_tv)
  {
!     smsg((char_u *)_("Opening the X display took %ld msec"), 
elapsed(start_tv));
  }
  # endif
  #endif
--- 1539,1554 ----
  
  #ifdef FEAT_X11
  
! # if defined(ELAPSED_TIMEVAL) \
        && (defined(FEAT_XCLIPBOARD) || defined(FEAT_TITLE))
  
  /*
   * Give a message about the elapsed time for opening the X window.
   */
      static void
! xopen_message(long elapsed_msec)
  {
!     smsg((char_u *)_("Opening the X display took %ld msec"), elapsed_msec);
  }
  # endif
  #endif
***************
*** 1864,1874 ****
  #endif
        if (x11_display != NULL)
        {
! # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
            if (p_verbose > 0)
            {
                verbose_enter();
!               xopen_message(&start_tv);
                verbose_leave();
            }
  # endif
--- 1847,1857 ----
  #endif
        if (x11_display != NULL)
        {
! # ifdef ELAPSED_FUNC
            if (p_verbose > 0)
            {
                verbose_enter();
!               xopen_message(ELAPSED_FUNC(start_tv));
                verbose_leave();
            }
  # endif
***************
*** 4630,4637 ****
                    ga_init2(&ga, 1, BUFLEN);
  
                noread_cnt = 0;
! # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
!               gettimeofday(&start_tv, NULL);
  # endif
                for (;;)
                {
--- 4613,4620 ----
                    ga_init2(&ga, 1, BUFLEN);
  
                noread_cnt = 0;
! # ifdef ELAPSED_FUNC
!               ELAPSED_INIT(start_tv);
  # endif
                for (;;)
                {
***************
*** 4666,4673 ****
                          /* Get extra characters when we don't have any.
                           * Reset the counter and timer. */
                          noread_cnt = 0;
! # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
!                         gettimeofday(&start_tv, NULL);
  # endif
                          len = ui_inchar(ta_buf, BUFLEN, 10L, 0);
                      }
--- 4649,4656 ----
                          /* Get extra characters when we don't have any.
                           * Reset the counter and timer. */
                          noread_cnt = 0;
! # ifdef ELAPSED_FUNC
!                         ELAPSED_INIT(start_tv);
  # endif
                          len = ui_inchar(ta_buf, BUFLEN, 10L, 0);
                      }
***************
*** 4886,4895 ****
                        if (got_int)
                            break;
  
! # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
                        if (wait_pid == 0)
                        {
!                           long            msec = elapsed(&start_tv);
  
                            /* Avoid that we keep looping here without
                             * checking for a CTRL-C for a long time.  Don't
--- 4869,4878 ----
                        if (got_int)
                            break;
  
! # ifdef ELAPSED_FUNC
                        if (wait_pid == 0)
                        {
!                           long        msec = ELAPSED_FUNC(start_tv);
  
                            /* Avoid that we keep looping here without
                             * checking for a CTRL-C for a long time.  Don't
***************
*** 5632,5646 ****
      /* May retry getting characters after an event was handled. */
  # define MAY_LOOP
  
! # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
      /* Remember at what time we started, so that we know how much longer we
       * should wait after being interrupted. */
- #  define USE_START_TV
      long          start_msec = msec;
!     struct timeval  start_tv;
  
      if (msec > 0)
!       gettimeofday(&start_tv, NULL);
  # endif
  
      /* Handle being called recursively.  This may happen for the session
--- 5615,5628 ----
      /* May retry getting characters after an event was handled. */
  # define MAY_LOOP
  
! # ifdef ELAPSED_FUNC
      /* Remember at what time we started, so that we know how much longer we
       * should wait after being interrupted. */
      long          start_msec = msec;
!     ELAPSED_TYPE  start_tv;
  
      if (msec > 0)
!       ELAPSED_INIT(start_tv);
  # endif
  
      /* Handle being called recursively.  This may happen for the session
***************
*** 5947,5955 ****
        /* We're going to loop around again, find out for how long */
        if (msec > 0)
        {
! # ifdef USE_START_TV
            /* Compute remaining wait time. */
!           msec = start_msec - elapsed(&start_tv);
  # else
            /* Guess we got interrupted halfway. */
            msec = msec / 2;
--- 5929,5937 ----
        /* We're going to loop around again, find out for how long */
        if (msec > 0)
        {
! # ifdef ELAPSED_FUNC
            /* Compute remaining wait time. */
!           msec = start_msec - ELAPSED_FUNC(start_tv);
  # else
            /* Guess we got interrupted halfway. */
            msec = msec / 2;
***************
*** 7046,7056 ****
  #if defined(HAVE_SETJMP_H)
        int (*oldIOhandler)();
  #endif
! # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
!       struct timeval  start_tv;
  
        if (p_verbose > 0)
!           gettimeofday(&start_tv, NULL);
  # endif
  
        /* Ignore X errors while opening the display */
--- 7028,7038 ----
  #if defined(HAVE_SETJMP_H)
        int (*oldIOhandler)();
  #endif
! # ifdef ELAPSED_FUNC
!       ELAPSED_TYPE  start_tv;
  
        if (p_verbose > 0)
!           ELAPSED_INIT(start_tv);
  # endif
  
        /* Ignore X errors while opening the display */
***************
*** 7092,7102 ****
        /* Catch terminating error of the X server connection. */
        (void)XSetIOErrorHandler(x_IOerror_handler);
  
! # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
        if (p_verbose > 0)
        {
            verbose_enter();
!           xopen_message(&start_tv);
            verbose_leave();
        }
  # endif
--- 7074,7084 ----
        /* Catch terminating error of the X server connection. */
        (void)XSetIOErrorHandler(x_IOerror_handler);
  
! # ifdef ELAPSED_FUNC
        if (p_verbose > 0)
        {
            verbose_enter();
!           xopen_message(ELAPSED_FUNC(start_tv));
            verbose_leave();
        }
  # endif
*** ../vim-8.0.0096/src/misc2.c 2016-11-10 20:01:41.193582919 +0100
--- src/misc2.c 2016-11-24 16:57:53.768987660 +0100
***************
*** 6263,6265 ****
--- 6263,6296 ----
  # endif
  }
  #endif
+ 
+ #ifdef ELAPSED_TIMEVAL  /* proto is defined in vim.h */
+ /*
+  * Return time in msec since "start_tv".
+  */
+     long
+ elapsed(struct timeval *start_tv)
+ {
+     struct timeval  now_tv;
+ 
+     gettimeofday(&now_tv, NULL);
+     return (now_tv.tv_sec - start_tv->tv_sec) * 1000L
+        + (now_tv.tv_usec - start_tv->tv_usec) / 1000L;
+ }
+ #endif
+ 
+ #ifdef ELAPSED_TICKCOUNT
+ /*
+  * Return time in msec since "start_tick".
+  */
+     long
+ elapsed(DWORD start_tick)
+ {
+     DWORD     now = GetTickCount();
+ 
+     if (now < start_tick)
+       /* overflow */
+       return (long)now;
+     return (long)now - (long)start_tick;
+ }
+ #endif
*** ../vim-8.0.0096/src/vim.h   2016-11-10 20:01:41.201582868 +0100
--- src/vim.h   2016-11-24 16:58:55.288576323 +0100
***************
*** 2503,2506 ****
--- 2503,2522 ----
  # define OPEN_CHR_FILES
  #endif
  
+ #if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+ # define ELAPSED_TIMEVAL
+ # define ELAPSED_INIT(v) gettimeofday(&v, NULL)
+ # define ELAPSED_FUNC(v) elapsed(&v)
+ # define ELAPSED_TYPE struct timeval
+     long elapsed(struct timeval *start_tv);
+ #else
+ # if defined(WIN32)
+ #  define ELAPSED_TICKCOUNT
+ #  define ELAPSED_INIT(v) v = GetTickCount
+ #  define ELAPSED_FUNC(v) elapsed(v)
+ #  define ELAPSED_TYPE DWORD
+     long elapsed(DWORD start_tick);
+ # endif
+ #endif
+ 
  #endif /* VIM__H */
*** ../vim-8.0.0096/src/os_win32.c      2016-11-19 17:28:41.577810144 +0100
--- src/os_win32.c      2016-11-24 16:46:08.177711935 +0100
***************
*** 4287,4295 ****
                    /* Get extra characters when we don't have any.  Reset the
                     * counter and timer. */
                    noread_cnt = 0;
- # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
-                   gettimeofday(&start_tv, NULL);
- # endif
                    len = ui_inchar(ta_buf, BUFLEN, 10L, 0);
                }
                if (ta_len > 0 || len > 0)
--- 4287,4292 ----
*** ../vim-8.0.0096/src/channel.c       2016-11-17 17:25:28.208093136 +0100
--- src/channel.c       2016-11-24 17:04:11.666462247 +0100
***************
*** 3815,3820 ****
--- 3815,3825 ----
      int               ret = FALSE;
      int               r;
      ch_part_T part = PART_SOCK;
+ #ifdef ELAPSED_FUNC
+     ELAPSED_TYPE  start_tv;
+ 
+     ELAPSED_INIT(start_tv);
+ #endif
  
      ++safe_to_invoke_callback;
  
***************
*** 3859,3865 ****
            r = may_invoke_callback(channel, part);
            if (r == OK)
                ret = TRUE;
!           if (channel_unref(channel) || r == OK)
            {
                /* channel was freed or something was done, start over */
                channel = first_channel;
--- 3864,3877 ----
            r = may_invoke_callback(channel, part);
            if (r == OK)
                ret = TRUE;
!           if (channel_unref(channel) || (r == OK
! #ifdef ELAPSED_FUNC
!                       /* Limit the time we loop here to 100 msec, otherwise
!                        * Vim becomes unresponsive when the callback takes
!                        * more than a bit of time. */
!                       && ELAPSED_FUNC(start_tv) < 100L
! #endif
!                       ))
            {
                /* channel was freed or something was done, start over */
                channel = first_channel;
*** ../vim-8.0.0096/src/version.c       2016-11-24 15:09:03.413856612 +0100
--- src/version.c       2016-11-24 17:16:25.453392518 +0100
***************
*** 766,767 ****
--- 766,769 ----
  {   /* Add new patch number below this line */
+ /**/
+     97,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
39. You move into a new house and decide to Netscape before you landscape.

 /// 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