Mercurial > vim
comparison 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 |
comparison
equal
deleted
inserted
replaced
10308:c6e8a776a1ed | 10309:88331ee68367 |
---|---|
402 long wtime, /* don't use "time", MIPS cannot handle it */ | 402 long wtime, /* don't use "time", MIPS cannot handle it */ |
403 int tb_change_cnt) | 403 int tb_change_cnt) |
404 { | 404 { |
405 int len; | 405 int len; |
406 int interrupted = FALSE; | 406 int interrupted = FALSE; |
407 int did_start_blocking = FALSE; | |
407 long wait_time; | 408 long wait_time; |
409 long elapsed_time = 0; | |
408 #if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) | 410 #if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) |
409 struct timeval start_tv; | 411 struct timeval start_tv; |
410 | 412 |
411 gettimeofday(&start_tv, NULL); | 413 gettimeofday(&start_tv, NULL); |
412 #endif | 414 #endif |
413 | 415 |
414 #ifdef MESSAGE_QUEUE | 416 /* repeat until we got a character or waited long enough */ |
415 parse_queued_messages(); | |
416 #endif | |
417 | |
418 /* Check if window changed size while we were busy, perhaps the ":set | |
419 * columns=99" command was used. */ | |
420 while (do_resize) | |
421 handle_resize(); | |
422 | |
423 for (;;) | 417 for (;;) |
424 { | 418 { |
425 if (wtime >= 0) | 419 /* Check if window changed size while we were busy, perhaps the ":set |
426 wait_time = wtime; | 420 * columns=99" command was used. */ |
427 else | 421 while (do_resize) |
428 wait_time = p_ut; | |
429 #if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) | |
430 wait_time -= elapsed(&start_tv); | |
431 if (wait_time >= 0) | |
432 { | |
433 #endif | |
434 if (WaitForChar(wait_time, &interrupted)) | |
435 break; | |
436 | |
437 /* no character available */ | |
438 if (do_resize) | |
439 { | |
440 handle_resize(); | |
441 continue; | |
442 } | |
443 #ifdef FEAT_CLIENTSERVER | |
444 if (server_waiting()) | |
445 { | |
446 parse_queued_messages(); | |
447 continue; | |
448 } | |
449 #endif | |
450 #ifdef MESSAGE_QUEUE | |
451 if (interrupted) | |
452 { | |
453 parse_queued_messages(); | |
454 continue; | |
455 } | |
456 #endif | |
457 #if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) | |
458 } | |
459 #endif | |
460 if (wtime >= 0) | |
461 /* no character available within "wtime" */ | |
462 return 0; | |
463 | |
464 /* wtime == -1: no character available within 'updatetime' */ | |
465 #ifdef FEAT_AUTOCMD | |
466 if (trigger_cursorhold() && maxlen >= 3 | |
467 && !typebuf_changed(tb_change_cnt)) | |
468 { | |
469 buf[0] = K_SPECIAL; | |
470 buf[1] = KS_EXTRA; | |
471 buf[2] = (int)KE_CURSORHOLD; | |
472 return 3; | |
473 } | |
474 #endif | |
475 /* | |
476 * If there is no character available within 'updatetime' seconds | |
477 * flush all the swap files to disk. | |
478 * Also done when interrupted by SIGWINCH. | |
479 */ | |
480 before_blocking(); | |
481 break; | |
482 } | |
483 | |
484 /* repeat until we got a character */ | |
485 for (;;) | |
486 { | |
487 long wtime_now = -1L; | |
488 | |
489 while (do_resize) /* window changed size */ | |
490 handle_resize(); | 422 handle_resize(); |
491 | 423 |
492 #ifdef MESSAGE_QUEUE | 424 #ifdef MESSAGE_QUEUE |
493 parse_queued_messages(); | 425 parse_queued_messages(); |
494 | 426 #endif |
495 # ifdef FEAT_JOB_CHANNEL | 427 if (wtime < 0 && did_start_blocking) |
496 if (has_pending_job()) | 428 /* blocking and already waited for p_ut */ |
497 { | 429 wait_time = -1; |
498 /* Don't wait longer than a few seconds, checking for a finished | 430 else |
499 * job requires polling. */ | 431 { |
500 if (p_ut > 9000L) | 432 if (wtime >= 0) |
501 wtime_now = 1000L; | 433 wait_time = wtime; |
502 else | 434 else |
503 wtime_now = 10000L - p_ut; | 435 /* going to block after p_ut */ |
504 } | 436 wait_time = p_ut; |
505 # endif | 437 #if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) |
506 #endif | 438 elapsed_time = elapsed(&start_tv); |
439 #endif | |
440 wait_time -= elapsed_time; | |
441 if (wait_time < 0) | |
442 { | |
443 if (wtime >= 0) | |
444 /* no character available within "wtime" */ | |
445 return 0; | |
446 | |
447 if (wtime < 0) | |
448 { | |
449 /* no character available within 'updatetime' */ | |
450 did_start_blocking = TRUE; | |
451 #ifdef FEAT_AUTOCMD | |
452 if (trigger_cursorhold() && maxlen >= 3 | |
453 && !typebuf_changed(tb_change_cnt)) | |
454 { | |
455 buf[0] = K_SPECIAL; | |
456 buf[1] = KS_EXTRA; | |
457 buf[2] = (int)KE_CURSORHOLD; | |
458 return 3; | |
459 } | |
460 #endif | |
461 /* | |
462 * If there is no character available within 'updatetime' | |
463 * seconds flush all the swap files to disk. | |
464 * Also done when interrupted by SIGWINCH. | |
465 */ | |
466 before_blocking(); | |
467 continue; | |
468 } | |
469 } | |
470 } | |
471 | |
472 #ifdef FEAT_JOB_CHANNEL | |
473 /* Checking if a job ended requires polling. Do this every 100 msec. */ | |
474 if (has_pending_job() && (wait_time < 0 || wait_time > 100L)) | |
475 wait_time = 100L; | |
476 #endif | |
477 | |
507 /* | 478 /* |
508 * We want to be interrupted by the winch signal | 479 * We want to be interrupted by the winch signal |
509 * or by an event on the monitored file descriptors. | 480 * or by an event on the monitored file descriptors. |
510 */ | 481 */ |
511 if (!WaitForChar(wtime_now, &interrupted)) | 482 if (WaitForChar(wait_time, &interrupted)) |
512 { | 483 { |
513 if (do_resize) /* interrupted by SIGWINCH signal */ | 484 /* If input was put directly in typeahead buffer bail out here. */ |
514 continue; | 485 if (typebuf_changed(tb_change_cnt)) |
486 return 0; | |
487 | |
488 /* | |
489 * For some terminals we only get one character at a time. | |
490 * We want the get all available characters, so we could keep on | |
491 * trying until none is available | |
492 * For some other terminals this is quite slow, that's why we don't | |
493 * do it. | |
494 */ | |
495 len = read_from_input_buf(buf, (long)maxlen); | |
496 if (len > 0) | |
497 return len; | |
498 continue; | |
499 } | |
500 | |
501 /* no character available */ | |
502 #if !(defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)) | |
503 /* estimate the elapsed time */ | |
504 elapsed += wait_time; | |
505 #endif | |
506 | |
507 if (do_resize /* interrupted by SIGWINCH signal */ | |
508 #ifdef FEAT_CLIENTSERVER | |
509 || server_waiting() | |
510 #endif | |
515 #ifdef MESSAGE_QUEUE | 511 #ifdef MESSAGE_QUEUE |
516 if (interrupted || wtime_now > 0) | 512 || interrupted |
517 { | 513 #endif |
518 parse_queued_messages(); | 514 || wait_time > 0 |
519 continue; | 515 || !did_start_blocking) |
520 } | 516 continue; |
521 #endif | 517 |
522 return 0; | 518 /* no character available or interrupted */ |
523 } | 519 break; |
524 | 520 } |
525 /* If input was put directly in typeahead buffer bail out here. */ | 521 return 0; |
526 if (typebuf_changed(tb_change_cnt)) | |
527 return 0; | |
528 | |
529 /* | |
530 * For some terminals we only get one character at a time. | |
531 * We want the get all available characters, so we could keep on | |
532 * trying until none is available | |
533 * For some other terminals this is quite slow, that's why we don't do | |
534 * it. | |
535 */ | |
536 len = read_from_input_buf(buf, (long)maxlen); | |
537 if (len > 0) | |
538 return len; | |
539 } | |
540 } | 522 } |
541 | 523 |
542 static void | 524 static void |
543 handle_resize(void) | 525 handle_resize(void) |
544 { | 526 { |