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