[Date Prev][Date Next][Thread Prev][][Date Index][Thread Index]

Re: wait asynchronous process (was: Error process-filter/sentinel whenexec w3m-delete-buffer)



>> On Mon, 10 Nov 2003 14:08:57 +0900
>> 「大」== bg66@koka-in.org (OHASHI Akira) said as follows:

大> 上記ファイルで試しにやってみようとした所、スクラッチバファにコピー
大> してedebug-defun で実行すると nil になるのですが、
大> eval-print-last-sexp すると t が返ってしまいます。

基本的に,非同期プロセスの debug をする場合は debugger はあてになりま
せん.

debugger に入ると,debugger の命令を受け取るためにエディタコマンドルー
プに入ります.エディタコマンドループでは,非同期プロセスからの出力も受
け付けますから,実際に debugger を通す場合と比較して非同期プロセスの出
力を処理するタイミングが異なってきてしまい,全体として得られる結果も違っ
てきます.

大> なお、edebug した時の値は buffer-size が 12911 で file-attributes 
大> の値が 12889 です。

これは,process sentinel function が \nProcess cat finished を挿入した
ことによる違いだろうと思いますから,実際にはうまくいっているんじゃない
でしょうか.

大> それと、process-connection-type の値は影響しますか?

おっと,それは考慮していませんでした.XEmacs@Solaris が全滅だったのは, 
そのせいだったんですね.process-connection-type を考慮するように変更し
た検証用コードを末尾に添付しましたので,適当に eval-last-sexp で試して
みてください.

[emacs-w3m:06033] の末尾の結果と比較すると,XEamcs@Solaris が動く場合
があることが違っています.ただ,この試験は対象となるファイルのファイル
サイズによって結果がかなり違ってきそうです.例えば,手元で

$ ls -l /etc/wgetrc
-rw-r--r--    1 root     root         4028 2002-11-20 12:41 /etc/wgetrc

を対象としてやってみると,一番最初の「まず process-status を確認してか
ら accept-process-output する」例は成功率 0% に悪化しました.どうやら,
あまり大きすぎても発生しないようですねえ.

;; こういうタイミング依存の問題解決って(以下略)

-- 
土屋 雅稔 ( TSUCHIYA Masatoshi )

(or (fboundp 'with-current-buffer)
    (progn
      (defmacro with-current-buffer (buffer &rest body)
	"Execute the forms in BODY with BUFFER as the current buffer."
	(let ((orig-buffer (make-symbol "orig-buffer")))
	  (` (let (((, orig-buffer) (current-buffer)))
	       (unwind-protect
		   (progn
		     (set-buffer (, buffer))
		     (,@ body))
		 (set-buffer (, orig-buffer)))))))
      (put 'with-current-buffer 'edebug-form-spec '(form body))
      (put 'with-current-buffer 'lisp-indent-function 1)))

(or (fboundp 'with-temp-buffer)
    (progn
      (defmacro with-temp-buffer (&rest body)
	"Create a temporary buffer, and evaluate BODY there like `progn'."
	(let ((buffer (make-symbol "temp-buffer")))
	  (` (let (((, buffer) (generate-new-buffer " *temp*")))
	       (unwind-protect
		   (with-current-buffer (, buffer)
					(,@ body))
		 (and (buffer-name (, buffer))
		      (kill-buffer (, buffer))))))))
      (put 'with-temp-buffer 'edebug-form-spec '(body))
      (put 'with-temp-buffer 'lisp-indent-function 0)))

(defmacro async-test (&rest body)
  `(let ((file "/etc/bash_completion")
	 (times 20)
	 (count 0)
	 (success 0)
	 (process-connection-type
	  (not (or (and (memq system-type '(darwin macos))
			(let ((ver (shell-command-to-string "uname -r")))
			  (and (string-match "^\\([0-9]+\\)\\." ver)
			       (< (string-to-number (match-string 1 ver)) 7))))
		   (and (featurep 'xemacs)
			(string-match "solaris" system-configuration))))))
     (while (<= (setq count (1+ count)) times)
       (if (progn ,@body)
	   (setq success (1+ success))))
     (if (= success times)
	 (message "Success")
       (message "Fail (%d/%d)" success times))))
(put 'async-test 'edebug-form-spec '(body))

;; Emacs21.3@Linux       => Fail (18/20)
;; Emacs20.7@Linux       => Fail (18/20)
;; XEmacs21.4.6@Linux    => Success
;; Mule2.3-19.34@Linux   => Fail (16/20)
;; Emacs21.2@Solaris     => Success
;; Emacs20.7@Solaris     => Success
;; XEmacs21.2.9@Solaris  => Success
;; Mule2.3-19.34@Solaris => Success
(async-test
 (with-temp-buffer
   (let* ((coding-system-for-read 'binary)
	  (proc (start-process "cat" (current-buffer) "cat" file)))
     (set-process-sentinel proc 'ignore)
     (while (eq 'run (process-status proc))
       (accept-process-output nil 0 200))
     (= (buffer-size) (nth 7 (file-attributes file))))))

;; Emacs21.3@Linux       => Success
;; Emacs20.7@Linux       => Success
;; XEmacs21.4.6@Linux    => Endless Loop
;; Mule2.3-19.34@Linux   => Fail (19/20)
;; Emacs21.2@Solaris     => Success
;; Emacs20.7@Solaris     => Endless Loop
;; XEmacs21.2.9@Solaris  => Endless Loop
;; Mule2.3-19.34@Solaris => Success
(async-test
 (with-temp-buffer
   (let* ((coding-system-for-read 'binary)
	  (proc (start-process "cat" (current-buffer) "cat" file)))
     (set-process-sentinel proc 'ignore)
     (while (or (accept-process-output proc 0 0)
		(eq 'run (process-status proc))))
     (= (buffer-size) (nth 7 (file-attributes file))))))

;; Emacs21.3@Linux       => Success
;; Emacs20.7@Linux       => Fail (19/20)
;; XEmacs21.4.6@Linux    => Success
;; Mule2.3-19.34@Linux   => Success
;; Emacs21.2@Solaris     => Success
;; Emacs20.7@Solaris     => Success
;; XEmacs21.2.9@Solaris  => Success (slow!)
;; Mule2.3-19.34@Solaris => Success
(async-test
 (with-temp-buffer
   (let* ((coding-system-for-read 'binary)
	  (proc (start-process "cat" (current-buffer) "cat" file)))
     (set-process-sentinel proc 'ignore)
     (while (or (accept-process-output proc 0 200)
		(eq 'run (process-status proc))))
     (= (buffer-size) (nth 7 (file-attributes file))))))

;; Emacs21.3@Linux       => Fail(19/20)
;; Emacs20.7@Linux       => Success
;; XEmacs21.4.6@Linux    => Success
;; Mule2.3-19.34@Linux   => Success
;; Emacs21.2@Solaris     => Success (too slow!)
;; Emacs20.7@Solaris     => Success
;; XEmacs21.2.9@Solaris  => Success
;; Mule2.3-19.34@Solaris => Success
(async-test
 (with-temp-buffer
   (let* ((coding-system-for-read 'binary)
	  (proc (start-process "cat" (current-buffer) "cat" file)))
     (set-process-sentinel proc 'ignore)
     (while (or (not (sit-for 0.1))
		(eq 'run (process-status proc))))
     (= (buffer-size) (nth 7 (file-attributes file))))))