mirror of
https://github.com/vim/vim.git
synced 2025-09-26 04:04:07 -04:00
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.
This commit is contained in:
@@ -3815,6 +3815,11 @@ channel_parse_messages(void)
|
|||||||
int ret = FALSE;
|
int ret = FALSE;
|
||||||
int r;
|
int r;
|
||||||
ch_part_T part = PART_SOCK;
|
ch_part_T part = PART_SOCK;
|
||||||
|
#ifdef ELAPSED_FUNC
|
||||||
|
ELAPSED_TYPE start_tv;
|
||||||
|
|
||||||
|
ELAPSED_INIT(start_tv);
|
||||||
|
#endif
|
||||||
|
|
||||||
++safe_to_invoke_callback;
|
++safe_to_invoke_callback;
|
||||||
|
|
||||||
@@ -3859,7 +3864,14 @@ channel_parse_messages(void)
|
|||||||
r = may_invoke_callback(channel, part);
|
r = may_invoke_callback(channel, part);
|
||||||
if (r == OK)
|
if (r == OK)
|
||||||
ret = TRUE;
|
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 was freed or something was done, start over */
|
||||||
channel = first_channel;
|
channel = first_channel;
|
||||||
|
31
src/misc2.c
31
src/misc2.c
@@ -6263,3 +6263,34 @@ parse_queued_messages(void)
|
|||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
#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
|
||||||
|
@@ -376,21 +376,6 @@ mch_write(char_u *s, int len)
|
|||||||
RealWaitForChar(read_cmd_fd, p_wd, NULL, NULL);
|
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.
|
* mch_inchar(): low level input function.
|
||||||
* Get a characters from the keyboard.
|
* Get a characters from the keyboard.
|
||||||
@@ -411,10 +396,10 @@ mch_inchar(
|
|||||||
int did_start_blocking = FALSE;
|
int did_start_blocking = FALSE;
|
||||||
long wait_time;
|
long wait_time;
|
||||||
long elapsed_time = 0;
|
long elapsed_time = 0;
|
||||||
#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
|
#ifdef ELAPSED_FUNC
|
||||||
struct timeval start_tv;
|
ELAPSED_TYPE start_tv;
|
||||||
|
|
||||||
gettimeofday(&start_tv, NULL);
|
ELAPSED_INIT(start_tv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* repeat until we got a character or waited long enough */
|
/* repeat until we got a character or waited long enough */
|
||||||
@@ -438,8 +423,8 @@ mch_inchar(
|
|||||||
else
|
else
|
||||||
/* going to block after p_ut */
|
/* going to block after p_ut */
|
||||||
wait_time = p_ut;
|
wait_time = p_ut;
|
||||||
#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
|
#ifdef ELAPSED_FUNC
|
||||||
elapsed_time = elapsed(&start_tv);
|
elapsed_time = ELAPSED_FUNC(start_tv);
|
||||||
#endif
|
#endif
|
||||||
wait_time -= elapsed_time;
|
wait_time -= elapsed_time;
|
||||||
if (wait_time < 0)
|
if (wait_time < 0)
|
||||||
@@ -1554,18 +1539,16 @@ mch_input_isatty(void)
|
|||||||
|
|
||||||
#ifdef FEAT_X11
|
#ifdef FEAT_X11
|
||||||
|
|
||||||
# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) \
|
# if defined(ELAPSED_TIMEVAL) \
|
||||||
&& (defined(FEAT_XCLIPBOARD) || defined(FEAT_TITLE))
|
&& (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.
|
* Give a message about the elapsed time for opening the X window.
|
||||||
*/
|
*/
|
||||||
static void
|
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
|
||||||
#endif
|
#endif
|
||||||
@@ -1864,11 +1847,11 @@ get_x11_windis(void)
|
|||||||
#endif
|
#endif
|
||||||
if (x11_display != NULL)
|
if (x11_display != NULL)
|
||||||
{
|
{
|
||||||
# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
|
# ifdef ELAPSED_FUNC
|
||||||
if (p_verbose > 0)
|
if (p_verbose > 0)
|
||||||
{
|
{
|
||||||
verbose_enter();
|
verbose_enter();
|
||||||
xopen_message(&start_tv);
|
xopen_message(ELAPSED_FUNC(start_tv));
|
||||||
verbose_leave();
|
verbose_leave();
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
@@ -4630,8 +4613,8 @@ mch_call_shell(
|
|||||||
ga_init2(&ga, 1, BUFLEN);
|
ga_init2(&ga, 1, BUFLEN);
|
||||||
|
|
||||||
noread_cnt = 0;
|
noread_cnt = 0;
|
||||||
# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
|
# ifdef ELAPSED_FUNC
|
||||||
gettimeofday(&start_tv, NULL);
|
ELAPSED_INIT(start_tv);
|
||||||
# endif
|
# endif
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
@@ -4666,8 +4649,8 @@ mch_call_shell(
|
|||||||
/* Get extra characters when we don't have any.
|
/* Get extra characters when we don't have any.
|
||||||
* Reset the counter and timer. */
|
* Reset the counter and timer. */
|
||||||
noread_cnt = 0;
|
noread_cnt = 0;
|
||||||
# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
|
# ifdef ELAPSED_FUNC
|
||||||
gettimeofday(&start_tv, NULL);
|
ELAPSED_INIT(start_tv);
|
||||||
# endif
|
# endif
|
||||||
len = ui_inchar(ta_buf, BUFLEN, 10L, 0);
|
len = ui_inchar(ta_buf, BUFLEN, 10L, 0);
|
||||||
}
|
}
|
||||||
@@ -4886,10 +4869,10 @@ mch_call_shell(
|
|||||||
if (got_int)
|
if (got_int)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
|
# ifdef ELAPSED_FUNC
|
||||||
if (wait_pid == 0)
|
if (wait_pid == 0)
|
||||||
{
|
{
|
||||||
long msec = elapsed(&start_tv);
|
long msec = ELAPSED_FUNC(start_tv);
|
||||||
|
|
||||||
/* Avoid that we keep looping here without
|
/* Avoid that we keep looping here without
|
||||||
* checking for a CTRL-C for a long time. Don't
|
* 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. */
|
/* May retry getting characters after an event was handled. */
|
||||||
# define MAY_LOOP
|
# 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
|
/* Remember at what time we started, so that we know how much longer we
|
||||||
* should wait after being interrupted. */
|
* should wait after being interrupted. */
|
||||||
# define USE_START_TV
|
|
||||||
long start_msec = msec;
|
long start_msec = msec;
|
||||||
struct timeval start_tv;
|
ELAPSED_TYPE start_tv;
|
||||||
|
|
||||||
if (msec > 0)
|
if (msec > 0)
|
||||||
gettimeofday(&start_tv, NULL);
|
ELAPSED_INIT(start_tv);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
/* Handle being called recursively. This may happen for the session
|
/* 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 */
|
/* We're going to loop around again, find out for how long */
|
||||||
if (msec > 0)
|
if (msec > 0)
|
||||||
{
|
{
|
||||||
# ifdef USE_START_TV
|
# ifdef ELAPSED_FUNC
|
||||||
/* Compute remaining wait time. */
|
/* Compute remaining wait time. */
|
||||||
msec = start_msec - elapsed(&start_tv);
|
msec = start_msec - ELAPSED_FUNC(start_tv);
|
||||||
# else
|
# else
|
||||||
/* Guess we got interrupted halfway. */
|
/* Guess we got interrupted halfway. */
|
||||||
msec = msec / 2;
|
msec = msec / 2;
|
||||||
@@ -7046,11 +7028,11 @@ setup_term_clip(void)
|
|||||||
#if defined(HAVE_SETJMP_H)
|
#if defined(HAVE_SETJMP_H)
|
||||||
int (*oldIOhandler)();
|
int (*oldIOhandler)();
|
||||||
#endif
|
#endif
|
||||||
# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
|
# ifdef ELAPSED_FUNC
|
||||||
struct timeval start_tv;
|
ELAPSED_TYPE start_tv;
|
||||||
|
|
||||||
if (p_verbose > 0)
|
if (p_verbose > 0)
|
||||||
gettimeofday(&start_tv, NULL);
|
ELAPSED_INIT(start_tv);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
/* Ignore X errors while opening the display */
|
/* Ignore X errors while opening the display */
|
||||||
@@ -7092,11 +7074,11 @@ setup_term_clip(void)
|
|||||||
/* Catch terminating error of the X server connection. */
|
/* Catch terminating error of the X server connection. */
|
||||||
(void)XSetIOErrorHandler(x_IOerror_handler);
|
(void)XSetIOErrorHandler(x_IOerror_handler);
|
||||||
|
|
||||||
# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
|
# ifdef ELAPSED_FUNC
|
||||||
if (p_verbose > 0)
|
if (p_verbose > 0)
|
||||||
{
|
{
|
||||||
verbose_enter();
|
verbose_enter();
|
||||||
xopen_message(&start_tv);
|
xopen_message(ELAPSED_FUNC(start_tv));
|
||||||
verbose_leave();
|
verbose_leave();
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
@@ -4287,9 +4287,6 @@ mch_system_piped(char *cmd, int options)
|
|||||||
/* Get extra characters when we don't have any. Reset the
|
/* Get extra characters when we don't have any. Reset the
|
||||||
* counter and timer. */
|
* counter and timer. */
|
||||||
noread_cnt = 0;
|
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);
|
len = ui_inchar(ta_buf, BUFLEN, 10L, 0);
|
||||||
}
|
}
|
||||||
if (ta_len > 0 || len > 0)
|
if (ta_len > 0 || len > 0)
|
||||||
|
@@ -764,6 +764,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
97,
|
||||||
/**/
|
/**/
|
||||||
96,
|
96,
|
||||||
/**/
|
/**/
|
||||||
|
16
src/vim.h
16
src/vim.h
@@ -2503,4 +2503,20 @@ typedef enum
|
|||||||
# define OPEN_CHR_FILES
|
# define OPEN_CHR_FILES
|
||||||
#endif
|
#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 */
|
#endif /* VIM__H */
|
||||||
|
Reference in New Issue
Block a user