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
next prev 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).