|
From: | Wagemans, Peter |
Subject: | tramp (2.1.6); Unnecessary delays accept-process-output; proposed fix |
Date: | Wed, 30 Aug 2006 11:41:01 +0200 |
On 2006.02.20 I sent a mail to the list with the title
tramp (2.0.47); Unnecessary delays accept-process-output; proposed fix.
It involved the accept-process-output timeout which was set to 1
second in the tramp code. This means that emacs always waits a full
second for output from a subprocess. In my environment, this increased
total setup time for new connections by about nine seconds. The
proposed fix reduced the timeout to 0.1 second on architectures that
support it. [In my situation, much shorter timeouts were not
productive since they typically led to emacs doing more wait requests
until subprocess output was complete.]
Michael Albinus declined the patch for the 2.0 release for stability
reasons but encouraged investigation for 2.1.
Since I'm now looking at getting 2.1.6 working, below is a similar
patch for that tramp release. I can imagine other ways of doing it,
but this seemed a relatively simple approach.
Tramp 2.1 is better in total connection setup time and the improvement
is therefore less than for tramp 2.0 (I haven't made precise
measurements), but still I see no point in having unnecessarily long
wait times.
Regards,
Peter Wagemans
------------------------------------------------------------------------
--- tramp.el.old_200608180843 2006-08-08 12:00:40.000000000 +0200
+++ tramp.el 2006-08-18 09:47:39.595817600 +0200
@@ -1299,6 +1299,40 @@
:group 'tramp
:type '(choice (const nil) (const t) (const pty)))
+(defcustom tramp-accept-process-output-timeout
+
+;; Try to figure out whether the system supports waiting for
+;; fractional seconds by sleeping for a millisecond. This should
+;; generate an error if the support is lacking, according to the elisp
+;; 21.2-8 manual and the following code in dispnew.c (21.4a).
+
+;; #ifndef EMACS_HAS_USECS
+;; if (sec == 0 && usec != 0)
+;; error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE);
+;; #endif
+
+(condition-case nil
+ (progn (sleep-for 0 1) 0.1)
+ (error 1) )
+
+
+;; Documentation string:
+
+ "Time interval to listen for output from subprocesses.
+
+The default value is 0.1 second on systems that support waiting
+for fractional seconds. On systems without such support,
+fractional values are rounded down, thus values smaller than 1
+second result in a zero wait time. This could result in a busy
+loop with tramp wasting CPU cycles on matching regular
+expressions against incomplete subprocess output. Therefore the
+default value is 1 second on systems without wait support for
+fractional seconds."
+
+ :group 'tramp
+ :type 'number)
+
+
;;; Internal Variables:
(defvar tramp-md5-function
@@ -4943,7 +4977,7 @@
(while (not found)
;; Reread output once all actions have been performed.
;; Obviously, the output was not complete.
- (tramp-accept-process-output proc 1)
+ (tramp-accept-process-output proc tramp-accept-process-output-timeout)
(setq todo actions)
(while todo
(setq item (pop todo))
@@ -4973,14 +5007,40 @@
;; Utility functions.
-(defun tramp-accept-process-output (&optional proc timeout timeout-msecs)
+(defun tramp-accept-process-output (&optional proc timeout)
"Like `accept-process-output' for Tramp processes.
This is needed in order to hide `last-coding-system-used', which is set
-for process communication also."
+for process communication also. In contrast to accept-process-output,
+the timeout is a single floating point value, usually set from the
+tramp-accept-process-output-timeout variable."
+
(with-current-buffer (process-buffer proc)
(tramp-message proc 10 "%s %s" proc (process-status proc))
(let (buffer-read-only last-coding-system-used)
- (accept-process-output proc timeout timeout-msecs))
+
+ (if timeout
+ ;; Call accept-process-output with appropriate parameters
+ ;; based on timeout value. The elisp manual 2.8 for emacs
+ ;; 21.2 (latest on 20060217) says about
+ ;; accept-process-output: "The argument seconds need not be
+ ;; an integer. If it is a floating point number, this
+ ;; function waits for a fractional number of seconds."
+ ;; However, the implementation in emacs-21.4a (current on
+ ;; 20060217) accepts only integers:
+ ;;
+ ;; if (! NILP (timeout))
+ ;; {
+ ;; CHECK_NUMBER (timeout, 1);
+ ;; seconds = XINT (timeout);
+ ;;
+ ;; so we convert the wait time to seconds and microseconds.
+
+ (let ((secs (floor timeout))
+ (microsecs (floor (* (mod timeout 1) 1000000))))
+ (accept-process-output proc secs microsecs))
+ ;; else call without timeout parameters
+ (accept-process-output proc)))
+
(tramp-message proc 10 "\n%s" (buffer-string))))
(defun tramp-check-for-regexp (proc regexp)
@@ -5020,13 +5080,13 @@
timeout))
(with-timeout (timeout)
(while (not found)
- (tramp-accept-process-output proc 1)
+ (tramp-accept-process-output proc tramp-accept-process-output-timeout)
(unless (memq (process-status proc) '(run open))
(tramp-error proc 'file-error "Process has died"))
(setq found (tramp-check-for-regexp proc regexp))))))
(t
(while (not found)
- (tramp-accept-process-output proc 1)
+ (tramp-accept-process-output proc tramp-accept-process-output-timeout)
(unless (memq (process-status proc) '(run open))
(tramp-error proc 'file-error "Process has died"))
(setq found (tramp-check-for-regexp proc regexp)))))
------------------------------------------------------------------------
[Prev in Thread] | Current Thread | [Next in Thread] |