]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.0.0097 v8.0.0097
authorBram Moolenaar <Bram@vim.org>
Thu, 24 Nov 2016 16:22:50 +0000 (17:22 +0100)
committerBram Moolenaar <Bram@vim.org>
Thu, 24 Nov 2016 16:22:50 +0000 (17:22 +0100)
Problem:    When a channel callback consumes a lot of time Vim becomes
            unresponsive. (skywind)
Solution:   Bail out of checking channel readahead after 100 msec.

src/channel.c
src/misc2.c
src/os_unix.c
src/os_win32.c
src/version.c
src/vim.h

index 778a30e17c552a6da458999c54a2e83ca07ad453..19520e200753f8f28b67eddb0924d42b1da9e268 100644 (file)
@@ -3815,6 +3815,11 @@ channel_parse_messages(void)
     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,7 +3864,14 @@ channel_parse_messages(void)
            r = may_invoke_callback(channel, part);
            if (r == OK)
                ret = TRUE;
-           if (channel_unref(channel) || r == OK)
+           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;
index 27d26bece90d38ca3f14fc5f586a6122062ccec7..9fa11e3d25a4ae4aea5f212466792d791aa21557 100644 (file)
@@ -6263,3 +6263,34 @@ parse_queued_messages(void)
 # 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
index a63eb6e89196e8b22798c8d4a0958abc8e8c8e99..12fb33b7ae97609d30de27308186dc7901db2571 100644 (file)
@@ -376,21 +376,6 @@ mch_write(char_u *s, int len)
        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.
@@ -411,10 +396,10 @@ mch_inchar(
     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;
+#ifdef ELAPSED_FUNC
+    ELAPSED_TYPE start_tv;
 
-    gettimeofday(&start_tv, NULL);
+    ELAPSED_INIT(start_tv);
 #endif
 
     /* repeat until we got a character or waited long enough */
@@ -438,8 +423,8 @@ mch_inchar(
            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);
+#ifdef ELAPSED_FUNC
+           elapsed_time = ELAPSED_FUNC(start_tv);
 #endif
            wait_time -= elapsed_time;
            if (wait_time < 0)
@@ -1554,18 +1539,16 @@ mch_input_isatty(void)
 
 #ifdef FEAT_X11
 
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) \
+# if defined(ELAPSED_TIMEVAL) \
        && (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)
+xopen_message(long elapsed_msec)
 {
-    smsg((char_u *)_("Opening the X display took %ld msec"), elapsed(start_tv));
+    smsg((char_u *)_("Opening the X display took %ld msec"), elapsed_msec);
 }
 # endif
 #endif
@@ -1864,11 +1847,11 @@ get_x11_windis(void)
 #endif
        if (x11_display != NULL)
        {
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+# ifdef ELAPSED_FUNC
            if (p_verbose > 0)
            {
                verbose_enter();
-               xopen_message(&start_tv);
+               xopen_message(ELAPSED_FUNC(start_tv));
                verbose_leave();
            }
 # endif
@@ -4630,8 +4613,8 @@ mch_call_shell(
                    ga_init2(&ga, 1, BUFLEN);
 
                noread_cnt = 0;
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
-               gettimeofday(&start_tv, NULL);
+# ifdef ELAPSED_FUNC
+               ELAPSED_INIT(start_tv);
 # endif
                for (;;)
                {
@@ -4666,8 +4649,8 @@ mch_call_shell(
                          /* 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);
+# ifdef ELAPSED_FUNC
+                         ELAPSED_INIT(start_tv);
 # endif
                          len = ui_inchar(ta_buf, BUFLEN, 10L, 0);
                      }
@@ -4886,10 +4869,10 @@ mch_call_shell(
                        if (got_int)
                            break;
 
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+# ifdef ELAPSED_FUNC
                        if (wait_pid == 0)
                        {
-                           long            msec = elapsed(&start_tv);
+                           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,15 +5615,14 @@ RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED, int *interrupted)
     /* May retry getting characters after an event was handled. */
 # define MAY_LOOP
 
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+# ifdef ELAPSED_FUNC
     /* 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;
+    ELAPSED_TYPE  start_tv;
 
     if (msec > 0)
-       gettimeofday(&start_tv, NULL);
+       ELAPSED_INIT(start_tv);
 # endif
 
     /* Handle being called recursively.  This may happen for the session
@@ -5947,9 +5929,9 @@ select_eintr:
        /* We're going to loop around again, find out for how long */
        if (msec > 0)
        {
-# ifdef USE_START_TV
+# ifdef ELAPSED_FUNC
            /* Compute remaining wait time. */
-           msec = start_msec - elapsed(&start_tv);
+           msec = start_msec - ELAPSED_FUNC(start_tv);
 # else
            /* Guess we got interrupted halfway. */
            msec = msec / 2;
@@ -7046,11 +7028,11 @@ setup_term_clip(void)
 #if defined(HAVE_SETJMP_H)
        int (*oldIOhandler)();
 #endif
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
-       struct timeval  start_tv;
+# ifdef ELAPSED_FUNC
+       ELAPSED_TYPE  start_tv;
 
        if (p_verbose > 0)
-           gettimeofday(&start_tv, NULL);
+           ELAPSED_INIT(start_tv);
 # endif
 
        /* Ignore X errors while opening the display */
@@ -7092,11 +7074,11 @@ setup_term_clip(void)
        /* Catch terminating error of the X server connection. */
        (void)XSetIOErrorHandler(x_IOerror_handler);
 
-# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+# ifdef ELAPSED_FUNC
        if (p_verbose > 0)
        {
            verbose_enter();
-           xopen_message(&start_tv);
+           xopen_message(ELAPSED_FUNC(start_tv));
            verbose_leave();
        }
 # endif
index 34b2ca8384e940e11864a789d614dfd1636a12e7..23044381d03ebe3de9b45dabf2eeff390befdeb5 100644 (file)
@@ -4287,9 +4287,6 @@ mch_system_piped(char *cmd, int options)
                    /* 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)
index e259000c0fc5ed368e4d18a04cef7a5dcc63687f..076ed520ce80b40b8f27c13d040441e678d9e7bb 100644 (file)
@@ -764,6 +764,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    97,
 /**/
     96,
 /**/
index eec3e4f73f2067f5f9d0e0c96f33299dff4c9c82..c91e52bb2a3fe586673918a3f401b9b06dd660f0 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
@@ -2503,4 +2503,20 @@ typedef enum
 # 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 */