Mercurial > vim
comparison src/os_unix.c @ 10406:42911b233245 v8.0.0097
commit https://github.com/vim/vim/commit/833eb1d752426689051bf2001083359899536939
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Nov 24 17:22:50 2016 +0100
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.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 24 Nov 2016 17:30:04 +0100 |
parents | d3f0946b4a80 |
children | 56cb9538386c |
comparison
equal
deleted
inserted
replaced
10405:4d35d83f4537 | 10406:42911b233245 |
---|---|
374 ignored = (int)write(1, (char *)s, len); | 374 ignored = (int)write(1, (char *)s, len); |
375 if (p_wd) /* Unix is too fast, slow down a bit more */ | 375 if (p_wd) /* Unix is too fast, slow down a bit more */ |
376 RealWaitForChar(read_cmd_fd, p_wd, NULL, NULL); | 376 RealWaitForChar(read_cmd_fd, p_wd, NULL, NULL); |
377 } | 377 } |
378 | 378 |
379 #if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) | |
380 /* | |
381 * Return time in msec since "start_tv". | |
382 */ | |
383 static long | |
384 elapsed(struct timeval *start_tv) | |
385 { | |
386 struct timeval now_tv; | |
387 | |
388 gettimeofday(&now_tv, NULL); | |
389 return (now_tv.tv_sec - start_tv->tv_sec) * 1000L | |
390 + (now_tv.tv_usec - start_tv->tv_usec) / 1000L; | |
391 } | |
392 #endif | |
393 | |
394 /* | 379 /* |
395 * mch_inchar(): low level input function. | 380 * mch_inchar(): low level input function. |
396 * Get a characters from the keyboard. | 381 * Get a characters from the keyboard. |
397 * Return the number of characters that are available. | 382 * Return the number of characters that are available. |
398 * If wtime == 0 do not wait for characters. | 383 * If wtime == 0 do not wait for characters. |
409 int len; | 394 int len; |
410 int interrupted = FALSE; | 395 int interrupted = FALSE; |
411 int did_start_blocking = FALSE; | 396 int did_start_blocking = FALSE; |
412 long wait_time; | 397 long wait_time; |
413 long elapsed_time = 0; | 398 long elapsed_time = 0; |
414 #if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) | 399 #ifdef ELAPSED_FUNC |
415 struct timeval start_tv; | 400 ELAPSED_TYPE start_tv; |
416 | 401 |
417 gettimeofday(&start_tv, NULL); | 402 ELAPSED_INIT(start_tv); |
418 #endif | 403 #endif |
419 | 404 |
420 /* repeat until we got a character or waited long enough */ | 405 /* repeat until we got a character or waited long enough */ |
421 for (;;) | 406 for (;;) |
422 { | 407 { |
436 if (wtime >= 0) | 421 if (wtime >= 0) |
437 wait_time = wtime; | 422 wait_time = wtime; |
438 else | 423 else |
439 /* going to block after p_ut */ | 424 /* going to block after p_ut */ |
440 wait_time = p_ut; | 425 wait_time = p_ut; |
441 #if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) | 426 #ifdef ELAPSED_FUNC |
442 elapsed_time = elapsed(&start_tv); | 427 elapsed_time = ELAPSED_FUNC(start_tv); |
443 #endif | 428 #endif |
444 wait_time -= elapsed_time; | 429 wait_time -= elapsed_time; |
445 if (wait_time < 0) | 430 if (wait_time < 0) |
446 { | 431 { |
447 if (wtime >= 0) | 432 if (wtime >= 0) |
1552 return FALSE; | 1537 return FALSE; |
1553 } | 1538 } |
1554 | 1539 |
1555 #ifdef FEAT_X11 | 1540 #ifdef FEAT_X11 |
1556 | 1541 |
1557 # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) \ | 1542 # if defined(ELAPSED_TIMEVAL) \ |
1558 && (defined(FEAT_XCLIPBOARD) || defined(FEAT_TITLE)) | 1543 && (defined(FEAT_XCLIPBOARD) || defined(FEAT_TITLE)) |
1559 | 1544 |
1560 static void xopen_message(struct timeval *start_tv); | |
1561 | |
1562 /* | 1545 /* |
1563 * Give a message about the elapsed time for opening the X window. | 1546 * Give a message about the elapsed time for opening the X window. |
1564 */ | 1547 */ |
1565 static void | 1548 static void |
1566 xopen_message(struct timeval *start_tv) | 1549 xopen_message(long elapsed_msec) |
1567 { | 1550 { |
1568 smsg((char_u *)_("Opening the X display took %ld msec"), elapsed(start_tv)); | 1551 smsg((char_u *)_("Opening the X display took %ld msec"), elapsed_msec); |
1569 } | 1552 } |
1570 # endif | 1553 # endif |
1571 #endif | 1554 #endif |
1572 | 1555 |
1573 #if defined(FEAT_X11) && (defined(FEAT_TITLE) || defined(FEAT_XCLIPBOARD)) | 1556 #if defined(FEAT_X11) && (defined(FEAT_TITLE) || defined(FEAT_XCLIPBOARD)) |
1862 if (p_verbose > 0 && sig_alarm_called) | 1845 if (p_verbose > 0 && sig_alarm_called) |
1863 verb_msg((char_u *)_("Opening the X display timed out")); | 1846 verb_msg((char_u *)_("Opening the X display timed out")); |
1864 #endif | 1847 #endif |
1865 if (x11_display != NULL) | 1848 if (x11_display != NULL) |
1866 { | 1849 { |
1867 # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) | 1850 # ifdef ELAPSED_FUNC |
1868 if (p_verbose > 0) | 1851 if (p_verbose > 0) |
1869 { | 1852 { |
1870 verbose_enter(); | 1853 verbose_enter(); |
1871 xopen_message(&start_tv); | 1854 xopen_message(ELAPSED_FUNC(start_tv)); |
1872 verbose_leave(); | 1855 verbose_leave(); |
1873 } | 1856 } |
1874 # endif | 1857 # endif |
1875 if (test_x11_window(x11_display) == FAIL) | 1858 if (test_x11_window(x11_display) == FAIL) |
1876 { | 1859 { |
4628 | 4611 |
4629 if (options & SHELL_READ) | 4612 if (options & SHELL_READ) |
4630 ga_init2(&ga, 1, BUFLEN); | 4613 ga_init2(&ga, 1, BUFLEN); |
4631 | 4614 |
4632 noread_cnt = 0; | 4615 noread_cnt = 0; |
4633 # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) | 4616 # ifdef ELAPSED_FUNC |
4634 gettimeofday(&start_tv, NULL); | 4617 ELAPSED_INIT(start_tv); |
4635 # endif | 4618 # endif |
4636 for (;;) | 4619 for (;;) |
4637 { | 4620 { |
4638 /* | 4621 /* |
4639 * Check if keys have been typed, write them to the child | 4622 * Check if keys have been typed, write them to the child |
4664 if (ta_len == 0) | 4647 if (ta_len == 0) |
4665 { | 4648 { |
4666 /* Get extra characters when we don't have any. | 4649 /* Get extra characters when we don't have any. |
4667 * Reset the counter and timer. */ | 4650 * Reset the counter and timer. */ |
4668 noread_cnt = 0; | 4651 noread_cnt = 0; |
4669 # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) | 4652 # ifdef ELAPSED_FUNC |
4670 gettimeofday(&start_tv, NULL); | 4653 ELAPSED_INIT(start_tv); |
4671 # endif | 4654 # endif |
4672 len = ui_inchar(ta_buf, BUFLEN, 10L, 0); | 4655 len = ui_inchar(ta_buf, BUFLEN, 10L, 0); |
4673 } | 4656 } |
4674 if (ta_len > 0 || len > 0) | 4657 if (ta_len > 0 || len > 0) |
4675 { | 4658 { |
4884 cursor_on(); | 4867 cursor_on(); |
4885 out_flush(); | 4868 out_flush(); |
4886 if (got_int) | 4869 if (got_int) |
4887 break; | 4870 break; |
4888 | 4871 |
4889 # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) | 4872 # ifdef ELAPSED_FUNC |
4890 if (wait_pid == 0) | 4873 if (wait_pid == 0) |
4891 { | 4874 { |
4892 long msec = elapsed(&start_tv); | 4875 long msec = ELAPSED_FUNC(start_tv); |
4893 | 4876 |
4894 /* Avoid that we keep looping here without | 4877 /* Avoid that we keep looping here without |
4895 * checking for a CTRL-C for a long time. Don't | 4878 * checking for a CTRL-C for a long time. Don't |
4896 * break out too often to avoid losing typeahead. */ | 4879 * break out too often to avoid losing typeahead. */ |
4897 if (msec > 2000) | 4880 if (msec > 2000) |
5630 static int busy = FALSE; | 5613 static int busy = FALSE; |
5631 | 5614 |
5632 /* May retry getting characters after an event was handled. */ | 5615 /* May retry getting characters after an event was handled. */ |
5633 # define MAY_LOOP | 5616 # define MAY_LOOP |
5634 | 5617 |
5635 # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) | 5618 # ifdef ELAPSED_FUNC |
5636 /* Remember at what time we started, so that we know how much longer we | 5619 /* Remember at what time we started, so that we know how much longer we |
5637 * should wait after being interrupted. */ | 5620 * should wait after being interrupted. */ |
5638 # define USE_START_TV | |
5639 long start_msec = msec; | 5621 long start_msec = msec; |
5640 struct timeval start_tv; | 5622 ELAPSED_TYPE start_tv; |
5641 | 5623 |
5642 if (msec > 0) | 5624 if (msec > 0) |
5643 gettimeofday(&start_tv, NULL); | 5625 ELAPSED_INIT(start_tv); |
5644 # endif | 5626 # endif |
5645 | 5627 |
5646 /* Handle being called recursively. This may happen for the session | 5628 /* Handle being called recursively. This may happen for the session |
5647 * manager stuff, it may save the file, which does a breakcheck. */ | 5629 * manager stuff, it may save the file, which does a breakcheck. */ |
5648 if (busy) | 5630 if (busy) |
5945 # endif | 5927 # endif |
5946 | 5928 |
5947 /* We're going to loop around again, find out for how long */ | 5929 /* We're going to loop around again, find out for how long */ |
5948 if (msec > 0) | 5930 if (msec > 0) |
5949 { | 5931 { |
5950 # ifdef USE_START_TV | 5932 # ifdef ELAPSED_FUNC |
5951 /* Compute remaining wait time. */ | 5933 /* Compute remaining wait time. */ |
5952 msec = start_msec - elapsed(&start_tv); | 5934 msec = start_msec - ELAPSED_FUNC(start_tv); |
5953 # else | 5935 # else |
5954 /* Guess we got interrupted halfway. */ | 5936 /* Guess we got interrupted halfway. */ |
5955 msec = msec / 2; | 5937 msec = msec / 2; |
5956 # endif | 5938 # endif |
5957 if (msec <= 0) | 5939 if (msec <= 0) |
7044 { | 7026 { |
7045 int (*oldhandler)(); | 7027 int (*oldhandler)(); |
7046 #if defined(HAVE_SETJMP_H) | 7028 #if defined(HAVE_SETJMP_H) |
7047 int (*oldIOhandler)(); | 7029 int (*oldIOhandler)(); |
7048 #endif | 7030 #endif |
7049 # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) | 7031 # ifdef ELAPSED_FUNC |
7050 struct timeval start_tv; | 7032 ELAPSED_TYPE start_tv; |
7051 | 7033 |
7052 if (p_verbose > 0) | 7034 if (p_verbose > 0) |
7053 gettimeofday(&start_tv, NULL); | 7035 ELAPSED_INIT(start_tv); |
7054 # endif | 7036 # endif |
7055 | 7037 |
7056 /* Ignore X errors while opening the display */ | 7038 /* Ignore X errors while opening the display */ |
7057 oldhandler = XSetErrorHandler(x_error_check); | 7039 oldhandler = XSetErrorHandler(x_error_check); |
7058 | 7040 |
7090 } | 7072 } |
7091 | 7073 |
7092 /* Catch terminating error of the X server connection. */ | 7074 /* Catch terminating error of the X server connection. */ |
7093 (void)XSetIOErrorHandler(x_IOerror_handler); | 7075 (void)XSetIOErrorHandler(x_IOerror_handler); |
7094 | 7076 |
7095 # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) | 7077 # ifdef ELAPSED_FUNC |
7096 if (p_verbose > 0) | 7078 if (p_verbose > 0) |
7097 { | 7079 { |
7098 verbose_enter(); | 7080 verbose_enter(); |
7099 xopen_message(&start_tv); | 7081 xopen_message(ELAPSED_FUNC(start_tv)); |
7100 verbose_leave(); | 7082 verbose_leave(); |
7101 } | 7083 } |
7102 # endif | 7084 # endif |
7103 | 7085 |
7104 /* Create a Shell to make converters work. */ | 7086 /* Create a Shell to make converters work. */ |