diff options
| author | Ian Kelling | 2015-07-05 17:00:26 -0700 |
|---|---|---|
| committer | Paul Eggert | 2015-07-05 19:21:49 -0700 |
| commit | 12a2691fb254db20607b2067a12b795a6d7c6649 (patch) | |
| tree | 724a4d09a3d680b1bfd59e0b44597168cffe3d78 /src/process.c | |
| parent | 6e2fcc213d4569992009480cf298536407cea4d2 (diff) | |
| download | emacs-12a2691fb254db20607b2067a12b795a6d7c6649.tar.gz emacs-12a2691fb254db20607b2067a12b795a6d7c6649.zip | |
Don't return as fast reading any process output
* src/process.c (wait_reading_process_output):
The patch for Bug#17647 returns too fast sometimes when reading
from any processes. Revert part of it, and limit the timeout more
sensibly (Bug#20978).
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 66 |
1 files changed, 43 insertions, 23 deletions
diff --git a/src/process.c b/src/process.c index 325c069bd5c..8e046a6dd11 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -4585,7 +4585,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4585 | bool no_avail; | 4585 | bool no_avail; |
| 4586 | int xerrno; | 4586 | int xerrno; |
| 4587 | Lisp_Object proc; | 4587 | Lisp_Object proc; |
| 4588 | struct timespec timeout, end_time; | 4588 | struct timespec timeout, end_time, timer_delay; |
| 4589 | struct timespec got_output_end_time = invalid_timespec (); | ||
| 4589 | enum { MINIMUM = -1, TIMEOUT, INFINITY } wait; | 4590 | enum { MINIMUM = -1, TIMEOUT, INFINITY } wait; |
| 4590 | int got_some_output = -1; | 4591 | int got_some_output = -1; |
| 4591 | ptrdiff_t count = SPECPDL_INDEX (); | 4592 | ptrdiff_t count = SPECPDL_INDEX (); |
| @@ -4618,7 +4619,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4618 | 4619 | ||
| 4619 | while (1) | 4620 | while (1) |
| 4620 | { | 4621 | { |
| 4621 | bool timeout_reduced_for_timers = false; | 4622 | bool process_skipped = false; |
| 4622 | 4623 | ||
| 4623 | /* If calling from keyboard input, do not quit | 4624 | /* If calling from keyboard input, do not quit |
| 4624 | since we want to return C-g as an input character. | 4625 | since we want to return C-g as an input character. |
| @@ -4632,10 +4633,6 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4632 | if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell))) | 4633 | if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell))) |
| 4633 | break; | 4634 | break; |
| 4634 | 4635 | ||
| 4635 | /* After reading input, vacuum up any leftovers without waiting. */ | ||
| 4636 | if (0 <= got_some_output) | ||
| 4637 | wait = MINIMUM; | ||
| 4638 | |||
| 4639 | /* Compute time from now till when time limit is up. */ | 4636 | /* Compute time from now till when time limit is up. */ |
| 4640 | /* Exit if already run out. */ | 4637 | /* Exit if already run out. */ |
| 4641 | if (wait == TIMEOUT) | 4638 | if (wait == TIMEOUT) |
| @@ -4655,8 +4652,6 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4655 | if (NILP (wait_for_cell) | 4652 | if (NILP (wait_for_cell) |
| 4656 | && just_wait_proc >= 0) | 4653 | && just_wait_proc >= 0) |
| 4657 | { | 4654 | { |
| 4658 | struct timespec timer_delay; | ||
| 4659 | |||
| 4660 | do | 4655 | do |
| 4661 | { | 4656 | { |
| 4662 | unsigned old_timers_run = timers_run; | 4657 | unsigned old_timers_run = timers_run; |
| @@ -4687,19 +4682,9 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4687 | && requeued_events_pending_p ()) | 4682 | && requeued_events_pending_p ()) |
| 4688 | break; | 4683 | break; |
| 4689 | 4684 | ||
| 4690 | if (timespec_valid_p (timer_delay)) | 4685 | /* This is so a breakpoint can be put here. */ |
| 4691 | { | 4686 | if (!timespec_valid_p (timer_delay)) |
| 4692 | if (timespec_cmp (timer_delay, timeout) < 0) | ||
| 4693 | { | ||
| 4694 | timeout = timer_delay; | ||
| 4695 | timeout_reduced_for_timers = true; | ||
| 4696 | } | ||
| 4697 | } | ||
| 4698 | else | ||
| 4699 | { | ||
| 4700 | /* This is so a breakpoint can be put here. */ | ||
| 4701 | wait_reading_process_output_1 (); | 4687 | wait_reading_process_output_1 (); |
| 4702 | } | ||
| 4703 | } | 4688 | } |
| 4704 | 4689 | ||
| 4705 | /* Cause C-g and alarm signals to take immediate action, | 4690 | /* Cause C-g and alarm signals to take immediate action, |
| @@ -4869,6 +4854,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4869 | if (!XPROCESS (proc)->read_output_skip) | 4854 | if (!XPROCESS (proc)->read_output_skip) |
| 4870 | continue; | 4855 | continue; |
| 4871 | FD_CLR (channel, &Available); | 4856 | FD_CLR (channel, &Available); |
| 4857 | process_skipped = true; | ||
| 4872 | XPROCESS (proc)->read_output_skip = 0; | 4858 | XPROCESS (proc)->read_output_skip = 0; |
| 4873 | if (XPROCESS (proc)->read_output_delay < adaptive_nsecs) | 4859 | if (XPROCESS (proc)->read_output_delay < adaptive_nsecs) |
| 4874 | adaptive_nsecs = XPROCESS (proc)->read_output_delay; | 4860 | adaptive_nsecs = XPROCESS (proc)->read_output_delay; |
| @@ -4878,6 +4864,29 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4878 | process_output_skip = 0; | 4864 | process_output_skip = 0; |
| 4879 | } | 4865 | } |
| 4880 | 4866 | ||
| 4867 | /* If we've got some output and haven't limited our timeout | ||
| 4868 | with adaptive read buffering, limit it. */ | ||
| 4869 | if (got_some_output > 0 && !process_skipped | ||
| 4870 | && (timeout.tv_sec | ||
| 4871 | || timeout.tv_nsec > READ_OUTPUT_DELAY_INCREMENT)) | ||
| 4872 | timeout = make_timespec (0, READ_OUTPUT_DELAY_INCREMENT); | ||
| 4873 | |||
| 4874 | |||
| 4875 | if (NILP (wait_for_cell) && just_wait_proc >= 0 | ||
| 4876 | && timespec_valid_p (timer_delay) | ||
| 4877 | && timespec_cmp (timer_delay, timeout) < 0) | ||
| 4878 | { | ||
| 4879 | struct timespec timeout_abs = timespec_add (current_timespec (), | ||
| 4880 | timeout); | ||
| 4881 | if (!timespec_valid_p (got_output_end_time) | ||
| 4882 | || timespec_cmp (timeout_abs, | ||
| 4883 | got_output_end_time) < 0) | ||
| 4884 | got_output_end_time = timeout_abs; | ||
| 4885 | timeout = timer_delay; | ||
| 4886 | } | ||
| 4887 | else | ||
| 4888 | got_output_end_time = invalid_timespec (); | ||
| 4889 | |||
| 4881 | #if defined (HAVE_NS) | 4890 | #if defined (HAVE_NS) |
| 4882 | nfds = ns_select | 4891 | nfds = ns_select |
| 4883 | #elif defined (HAVE_GLIB) | 4892 | #elif defined (HAVE_GLIB) |
| @@ -4949,9 +4958,17 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4949 | /* If we woke up due to SIGWINCH, actually change size now. */ | 4958 | /* If we woke up due to SIGWINCH, actually change size now. */ |
| 4950 | do_pending_window_change (0); | 4959 | do_pending_window_change (0); |
| 4951 | 4960 | ||
| 4952 | if (wait < INFINITY && nfds == 0 && ! timeout_reduced_for_timers) | 4961 | if (nfds == 0) |
| 4953 | /* We waited the full specified time, so return now. */ | 4962 | { |
| 4954 | break; | 4963 | struct timespec now = current_timespec (); |
| 4964 | if ((timeout.tv_sec == 0 && timeout.tv_nsec == 0) | ||
| 4965 | || (wait == TIMEOUT && timespec_cmp (end_time, now) <= 0) | ||
| 4966 | || (!process_skipped && got_some_output > 0 | ||
| 4967 | && (!timespec_valid_p (got_output_end_time) | ||
| 4968 | || timespec_cmp (got_output_end_time, now) <= 0))) | ||
| 4969 | break; | ||
| 4970 | } | ||
| 4971 | |||
| 4955 | if (nfds < 0) | 4972 | if (nfds < 0) |
| 4956 | { | 4973 | { |
| 4957 | if (xerrno == EINTR) | 4974 | if (xerrno == EINTR) |
| @@ -5079,6 +5096,9 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 5079 | got_some_output = nread; | 5096 | got_some_output = nread; |
| 5080 | if (nread > 0) | 5097 | if (nread > 0) |
| 5081 | { | 5098 | { |
| 5099 | /* Vacuum up any leftovers without waiting. */ | ||
| 5100 | if (wait_proc == XPROCESS (proc)) | ||
| 5101 | wait = MINIMUM; | ||
| 5082 | /* Since read_process_output can run a filter, | 5102 | /* Since read_process_output can run a filter, |
| 5083 | which can call accept-process-output, | 5103 | which can call accept-process-output, |
| 5084 | don't try to read from any other processes | 5104 | don't try to read from any other processes |