Mercurial > vim
diff src/os_unix.c @ 10309:88331ee68367 v8.0.0050
commit https://github.com/vim/vim/commit/01688ad545ff0809ddad5c8fa6b149dc5d67312b
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Oct 27 20:00:07 2016 +0200
patch 8.0.0050
Problem: An exiting job is detected with a large latency.
Solution: Check for pending job more often. (Ozaki Kiichi) Change the
double loop in mch_inchar() into one.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 27 Oct 2016 20:15:04 +0200 |
parents | c90f4cc9c3fe |
children | 6ab770e97152 |
line wrap: on
line diff
--- a/src/os_unix.c +++ b/src/os_unix.c @@ -404,139 +404,121 @@ mch_inchar( { int len; int interrupted = FALSE; + 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 -#ifdef MESSAGE_QUEUE - parse_queued_messages(); -#endif - - /* Check if window changed size while we were busy, perhaps the ":set - * columns=99" command was used. */ - while (do_resize) - handle_resize(); - + /* repeat until we got a character or waited long enough */ for (;;) { - if (wtime >= 0) - wait_time = wtime; - else - wait_time = p_ut; -#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) - wait_time -= elapsed(&start_tv); - if (wait_time >= 0) - { -#endif - if (WaitForChar(wait_time, &interrupted)) - break; - - /* no character available */ - if (do_resize) - { - handle_resize(); - continue; - } -#ifdef FEAT_CLIENTSERVER - if (server_waiting()) - { - parse_queued_messages(); - continue; - } -#endif -#ifdef MESSAGE_QUEUE - if (interrupted) - { - parse_queued_messages(); - continue; - } -#endif -#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) - } -#endif - if (wtime >= 0) - /* no character available within "wtime" */ - return 0; - - /* wtime == -1: no character available within 'updatetime' */ -#ifdef FEAT_AUTOCMD - if (trigger_cursorhold() && maxlen >= 3 - && !typebuf_changed(tb_change_cnt)) - { - buf[0] = K_SPECIAL; - buf[1] = KS_EXTRA; - buf[2] = (int)KE_CURSORHOLD; - return 3; - } -#endif - /* - * If there is no character available within 'updatetime' seconds - * flush all the swap files to disk. - * Also done when interrupted by SIGWINCH. - */ - before_blocking(); - break; - } - - /* repeat until we got a character */ - for (;;) - { - long wtime_now = -1L; - - while (do_resize) /* window changed size */ + /* Check if window changed size while we were busy, perhaps the ":set + * columns=99" command was used. */ + while (do_resize) handle_resize(); #ifdef MESSAGE_QUEUE parse_queued_messages(); - -# ifdef FEAT_JOB_CHANNEL - if (has_pending_job()) +#endif + if (wtime < 0 && did_start_blocking) + /* blocking and already waited for p_ut */ + wait_time = -1; + else { - /* Don't wait longer than a few seconds, checking for a finished - * job requires polling. */ - if (p_ut > 9000L) - wtime_now = 1000L; + if (wtime >= 0) + wait_time = wtime; else - wtime_now = 10000L - p_ut; + /* 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) + { + if (wtime >= 0) + /* no character available within "wtime" */ + return 0; + + if (wtime < 0) + { + /* no character available within 'updatetime' */ + did_start_blocking = TRUE; +#ifdef FEAT_AUTOCMD + if (trigger_cursorhold() && maxlen >= 3 + && !typebuf_changed(tb_change_cnt)) + { + buf[0] = K_SPECIAL; + buf[1] = KS_EXTRA; + buf[2] = (int)KE_CURSORHOLD; + return 3; + } +#endif + /* + * If there is no character available within 'updatetime' + * seconds flush all the swap files to disk. + * Also done when interrupted by SIGWINCH. + */ + before_blocking(); + continue; + } + } } -# endif -#endif + +#ifdef FEAT_JOB_CHANNEL + /* Checking if a job ended requires polling. Do this every 100 msec. */ + if (has_pending_job() && (wait_time < 0 || wait_time > 100L)) + wait_time = 100L; +#endif + /* * We want to be interrupted by the winch signal * or by an event on the monitored file descriptors. */ - if (!WaitForChar(wtime_now, &interrupted)) + if (WaitForChar(wait_time, &interrupted)) { - if (do_resize) /* interrupted by SIGWINCH signal */ - continue; -#ifdef MESSAGE_QUEUE - if (interrupted || wtime_now > 0) - { - parse_queued_messages(); - continue; - } -#endif - return 0; + /* If input was put directly in typeahead buffer bail out here. */ + if (typebuf_changed(tb_change_cnt)) + return 0; + + /* + * For some terminals we only get one character at a time. + * We want the get all available characters, so we could keep on + * trying until none is available + * For some other terminals this is quite slow, that's why we don't + * do it. + */ + len = read_from_input_buf(buf, (long)maxlen); + if (len > 0) + return len; + continue; } - /* If input was put directly in typeahead buffer bail out here. */ - if (typebuf_changed(tb_change_cnt)) - return 0; - - /* - * For some terminals we only get one character at a time. - * We want the get all available characters, so we could keep on - * trying until none is available - * For some other terminals this is quite slow, that's why we don't do - * it. - */ - len = read_from_input_buf(buf, (long)maxlen); - if (len > 0) - return len; - } + /* no character available */ +#if !(defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)) + /* estimate the elapsed time */ + elapsed += wait_time; +#endif + + if (do_resize /* interrupted by SIGWINCH signal */ +#ifdef FEAT_CLIENTSERVER + || server_waiting() +#endif +#ifdef MESSAGE_QUEUE + || interrupted +#endif + || wait_time > 0 + || !did_start_blocking) + continue; + + /* no character available or interrupted */ + break; + } + return 0; } static void