aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorIan Kelling2015-07-05 17:00:26 -0700
committerPaul Eggert2015-07-05 19:21:49 -0700
commit12a2691fb254db20607b2067a12b795a6d7c6649 (patch)
tree724a4d09a3d680b1bfd59e0b44597168cffe3d78 /src/process.c
parent6e2fcc213d4569992009480cf298536407cea4d2 (diff)
downloademacs-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.c66
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