unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Ian Kelling <ian@iankelling.org>
To: 20978@debbugs.gnu.org
Subject: bug#20978: [PATCH 6/7] Don't return as fast reading any process output
Date: Sat, 04 Jul 2015 05:47:07 -0700	[thread overview]
Message-ID: <87r3oohyyc.fsf@iankelling.org> (raw)
In-Reply-To: <87zj3ckso6.fsf@iankelling.org>


* src/process.c (wait_reading_process_output): The patch for
debbugs:17647 returns too fast sometimes when reading from any
processes. Revert part of it, and limit the timeout more
sensibly.

diff --git a/src/process.c b/src/process.c
index 538455c..cb48e5f 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,
   bool no_avail;
   int xerrno;
   Lisp_Object proc;
-  struct timespec timeout, end_time;
+  struct timespec timeout, end_time, timer_delay;
+  struct timespec got_output_end_time = invalid_timespec ();
   enum { MINIMUM, TIMEOUT, INFINITY } wait;
   int got_some_output = -1;
   ptrdiff_t count = SPECPDL_INDEX ();
@@ -4618,7 +4619,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,

   while (1)
     {
-      bool timeout_reduced_for_timers = false;
+      bool process_skipped = false;

       /* If calling from keyboard input, do not quit
         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,
       if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
        break;

-      /* After reading input, vacuum up any leftovers without waiting.  */
-      if (0 <= got_some_output)
-        wait = MINIMUM;
-
       /* Compute time from now till when time limit is up.  */
       /* Exit if already run out.  */
       if (wait == MINIMUM)
@@ -4661,8 +4658,6 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
       if (NILP (wait_for_cell)
          && just_wait_proc >= 0)
        {
-	  struct timespec timer_delay;
-
          do
            {
              unsigned old_timers_run = timers_run;
@@ -4693,19 +4688,9 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
              && requeued_events_pending_p ())
            break;

-          if (timespec_valid_p (timer_delay))
-            {
-              if (timespec_cmp (timer_delay, timeout) < 0)
-                {
-                  timeout = timer_delay;
-                  timeout_reduced_for_timers = true;
-                }
-            }
-          else
-            {
-              /* This is so a breakpoint can be put here.  */
+          /* This is so a breakpoint can be put here.  */
+          if (!timespec_valid_p (timer_delay))
               wait_reading_process_output_1 ();
-            }
         }

       /* Cause C-g and alarm signals to take immediate action,
@@ -4875,6 +4860,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
                      if (!XPROCESS (proc)->read_output_skip)
                        continue;
                      FD_CLR (channel, &Available);
+                      process_skipped = true;
                      XPROCESS (proc)->read_output_skip = 0;
                      if (XPROCESS (proc)->read_output_delay < adaptive_nsecs)
                        adaptive_nsecs = XPROCESS (proc)->read_output_delay;
@@ -4884,6 +4870,30 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
              process_output_skip = 0;
            }

+          /* If we've got some output and haven't limited our timeout
+           * with adaptive read buffering, limit it. */
+          if (got_some_output > 0 && !process_skipped
+              && (timeout.tv_sec
+                  || timeout.tv_nsec > READ_OUTPUT_DELAY_INCREMENT))
+            timeout = make_timespec (0, READ_OUTPUT_DELAY_INCREMENT);
+
+
+          if (NILP (wait_for_cell) && just_wait_proc >= 0
+              && timespec_valid_p (timer_delay)
+              && timespec_cmp (timer_delay, timeout) < 0)
+            {
+              struct timespec timeout_abs = timespec_add (current_timespec (),
+                                                          timeout);
+              if (!timespec_valid_p (got_output_end_time)
+                  || timespec_cmp (timeout_abs,
+                                   got_output_end_time) < 0)
+                got_output_end_time = timeout_abs;
+              timeout = timer_delay;
+            }
+          else
+            got_output_end_time = invalid_timespec ();
+
+
 #if defined (HAVE_NS)
           nfds = ns_select
 #elif defined (HAVE_GLIB)
@@ -4955,9 +4965,17 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
       /*  If we woke up due to SIGWINCH, actually change size now.  */
       do_pending_window_change (0);

-      if (wait != INFINITY && nfds == 0 && ! timeout_reduced_for_timers)
-	/* We waited the full specified time, so return now.  */
-	break;
+      if (nfds == 0)
+        {
+          struct timespec now = current_timespec ();
+          if ((timeout.tv_sec == 0 && timeout.tv_nsec == 0)
+              || (wait == TIMEOUT && timespec_cmp (end_time, now) <= 0)
+              || (!process_skipped && got_some_output > 0
+                  && (!timespec_valid_p (got_output_end_time)
+                      || timespec_cmp (got_output_end_time, now) <= 0)))
+            break;
+        }
+
       if (nfds < 0)
        {
          if (xerrno == EINTR)
@@ -5084,6 +5102,9 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
                got_some_output = nread;
              if (nread > 0)
                {
+                  /* vacuum up any leftovers without waiting.  */
+                  if (wait_proc == XPROCESS (proc))
+                    wait = MINIMUM;
                  /* Since read_process_output can run a filter,
                     which can call accept-process-output,
                     don't try to read from any other processes
--
2.4.5






  parent reply	other threads:[~2015-07-04 12:47 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-04 12:34 bug#20978: 25.0.50; [PATCH 0/7] Emacs can return too fast when reading from any processes Ian Kelling
2015-07-04 12:37 ` bug#20978: [PATCH 1/7] ; Minor cleanup of wait_reading_process_output Ian Kelling
2015-07-04 12:40 ` bug#20978: [PATCH 2/7] ; Remove ADAPTIVE_READ_BUFFERING ifdef Ian Kelling
2015-07-04 12:42 ` bug#20978: [PATCH 3/7] ; Rename local var to match function name Ian Kelling
2015-07-04 12:43 ` bug#20978: [PATCH 4/7] ; Rename local var nsecs to adaptive_nsecs Ian Kelling
2015-07-04 12:45 ` bug#20978: [PATCH 5/7] : Refactor timeouts in wait_reading_process_output Ian Kelling
2015-07-04 12:47 ` Ian Kelling [this message]
2015-07-04 12:48 ` bug#20978: [PATCH 7/7] Avoid returning early reading process output due to SIGIO Ian Kelling
2015-07-04 12:52 ` bug#20978: 25.0.50; [PATCH 0/7] Emacs can return too fast when reading from any processes Eli Zaretskii
2015-07-04 13:13   ` Ian Kelling
2015-07-04 13:25     ` Eli Zaretskii
2015-07-04 18:56       ` Stefan Monnier
2015-07-04 19:30         ` Eli Zaretskii
2015-07-04 22:20           ` Stefan Monnier
2015-07-04 13:22   ` Ian Kelling
2015-07-06  2:28 ` Paul Eggert
2015-07-06  6:44   ` Glenn Morris

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87r3oohyyc.fsf@iankelling.org \
    --to=ian@iankelling.org \
    --cc=20978@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).